<?php

namespace App\Http\Controllers;
use App\Models\Patient;
use App\Models\PatientAllergies;
use App\Models\PatientVitals;
use App\Models\PatientHealthHistory;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Session;
use App\Services\TwilioService;
use Carbon\Carbon;
use Illuminate\Support\Str;
use App\Services\LocationService;
use Exception;
use App\Services\ABDMService; 
use App\Mail\ActivationPatientMail;
use Illuminate\Support\Facades\Mail;   
use Illuminate\Support\Facades\Http;
use phpseclib3\Crypt\RSA;
use phpseclib3\Crypt\PublicKeyLoader;
use Illuminate\Support\Facades\Storage;   
use App\Services\QrCodeService; 

class PatientLoginController extends Controller
{

 protected $twilioService;
 protected $locationService;
 protected $abdmService;
     protected $qrCodeService;
     
  protected $authUrl = 'https://dev.abdm.gov.in/api/hiecm/gateway/v3/sessions';
    protected $certUrl = 'https://healthidsbx.abdm.gov.in/api/v1/auth/cert';
    protected $otpUrl = 'https://abhasbx.abdm.gov.in/abha/api/v3/enrollment/request/otp';
    protected $enrollUrl = 'https://abhasbx.abdm.gov.in/abha/api/v3/enrollment/enrol/byAadhaar';
    

    public function __construct(TwilioService $twilioService, QrCodeService $qrCodeService,  LocationService $locationService, ABDMService $abdmService)
    {
        
        $this->twilioService = $twilioService;
        $this->locationService = $locationService;
        $this->abdmService = $abdmService;
        $this->qrCodeService = $qrCodeService;  
        date_default_timezone_set('Asia/Kolkata'); // Set timezone to Asia/Kolkata    
         
    }
       

     
    public function index(Request $request)
    {
       
      if (!Auth::guard('patients')->check()) {   
      $dialingCode = null; 
      $ip = $this->locationService->getPublicIP(); 

      $countryCode = $this->locationService->getCountryCodeByIp($ip);

      if ($countryCode) {
          
          $dialingCode = $this->locationService->getDialingCode($countryCode);

       }


        return view('login.patient_login', compact('dialingCode'));
    } else{
        return redirect('/patient-portal'); 
    }
    }

    public function abhaRegister()
    {   
        return view('login.abha_register'); 
    } 
    
    
    public function getAbdmSessionToken(Request $request)
{
    $url = 'https://bluid.bluai.ai/api/bluid/getAbdmSessionToken';
   
    // You can accept Aadhaar dynamically or hardcode for now
    $aadhaarNumber = $request->input('aadhaarNumber', '279705665501');

    try {
       $response = Http::timeout(30)->post($url, [
    'aadhaarNumber' => $aadhaarNumber
]);
        if ($response->successful()) {
            return response()->json([
                'success' => true,
                'data' => $response->json()
            ]);
        } else {
            return response()->json([
                'success' => false,
                'error' => $response->body()
            ], $response->status());
        }
    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'error' => 'Exception: ' . $e->getMessage()
        ], 500);
    }
}


function detectCountryCodeFromLocation(array $location): ?string
{
    // Normalize input
    $stateCode = strtoupper($location['stateCode'] ?? '');
    $stateName = strtoupper($location['stateName'] ?? '');
    $pinCode = $location['pinCode'] ?? '';

    // 1. INDIA
    $indianStateCodes = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38'];
    $indianStateNames = ['UTTAR PRADESH','DELHI','MAHARASHTRA','PUNJAB','BIHAR','KARNATAKA','GUJARAT','WEST BENGAL','TAMIL NADU','KERALA','ANDHRA PRADESH'];

    if (in_array($stateCode, $indianStateCodes) || in_array($stateName, $indianStateNames) || preg_match('/^\d{6}$/', $pinCode)) {
        return '+91';
    }

    // 2. UNITED STATES
    $usStateCodes = ['AL','AK','AZ','AR','CA','CO','CT','DE','FL','GA','HI','ID','IL','IN','IA','KS','KY','LA','ME','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','OH','OK','OR','PA','RI','SC','SD','TN','TX','UT','VT','VA','WA','WV','WI','WY'];
    $usStateNames = ['CALIFORNIA','TEXAS','NEW YORK','FLORIDA','ILLINOIS'];

    if (in_array($stateCode, $usStateCodes) || in_array($stateName, $usStateNames) || preg_match('/^\d{5}$/', $pinCode)) {
        return '+1';
    }

    // 3. PAKISTAN
    $pakistaniStateNames = ['PUNJAB', 'SINDH', 'KPK', 'BALOCHISTAN', 'ISLAMABAD'];
    if (in_array($stateName, $pakistaniStateNames) || preg_match('/^\d{5}$/', $pinCode)) {
        // You could also match based on pinCode ranges like 7xxxx for Pakistan
        return '+92';
    }

    // Default: unknown
    return null;
}


 
public function verifyAbdmOtp(Request $request)  
{
    $url = 'https://bluid.bluai.ai/api/bluid/enrolAbhaByAadhaar';

    $aadhaarNumber = $request->input('aadhaarNumber');  // Add this
    $txnId = $request->input('txnId');
    $otpValue = $request->input('otpValue');
    $mobile = $request->input('mobile');     
    $accessToken = $request->input('accessToken');
    $publicKeyPem = $request->input('publicKeyPem'); 

    try {
        $response = Http::timeout(30)->post($url, [
            'aadhaarNumber' => $aadhaarNumber, // ? Important
            'txnId' => $txnId,
            'otpValue' => $otpValue,
            'mobile' => $mobile, 
            'accessToken' => $accessToken,    
            'publicKeyPem' => $publicKeyPem    
        ]);

        if ($response->successful()) {
        
        
                $patient = new Patient();
            
            $apiData = $response->json()['data']['ABHAProfile'] ?? null;
            
            $patient->first_name = $apiData['firstName'] ?? null;
            $patient->last_name = $apiData['lastName'] ?? null;
            $patient->date_of_birth = $apiData['dob'] ?? null;
            
            $gender = $apiData['gender'] ?? null;
            $patient->sex = $gender === 'M' ? 'Male' : ($gender === 'F' ? 'Female' : null);
            
            $patient->address = $apiData['address'] ?? null;
            $patient->patient_phone_number = $apiData['mobile'] ?? null;
            $patient->email = $apiData['email'] ?? null;
            $patient->aadhar_card_num = $aadhaarNumber; 
            
             $unique_id = $patient->patient_phone_number. '.' . substr($patient->aadhar_card_num, -4);
             
             $patient->unique_id = $unique_id;
            $patient->abha_number = isset($apiData['ABHANumber']) 
                                      ? str_replace('-', '', $apiData['ABHANumber']) 
                                      : null;        
               
            if (!empty($apiData['photo'])) {
              $fileName = 'photo_' . time() . '.jpg';
              $photoData = base64_decode($apiData['photo']);
              Storage::disk('public')->put('photos/' . $fileName, $photoData);
              $patient->photo = $fileName;
            }
 
 
             $location = [
                'stateCode' => $apiData['stateCode'],
                'stateName' => $apiData['stateName'],
                'pinCode'   => $apiData['pinCode'], 
            ];
            
            $countryCode = $this->detectCountryCodeFromLocation($location);        
            
            
               $patient->patient_phone_num_country_code = $countryCode ?? '+91'; // Default to +91 for India
               
               
        $qr_text = "Patient Information:\n--------------------------\n\n";
        $qr_text .= $patient->first_name ? "First Name: {$patient->first_name}\n\n" : '';
        $qr_text .= $patient->last_name ? "Last Name: {$patient->last_name}\n\n" : '';
        $qr_text .= $patient->date_of_birth ? "Date of Birth: {$patient->date_of_birth}\n\n" : '';
        $qr_text .= $patient->sex ? "Sex: {$patient->sex}\n\n" : '';
        $qr_text .= $patient->address ? "Address: {$patient->address}\n\n" : '';
        $qr_text .= $patient->email ? "Email: {$patient->email}\n\n" : '';
        $qr_text .= $patient->patient_phone_number ? "Phone Number: {$patient->patient_phone_number}\n\n" : '';
        $qr_text .= $countryCode ? "Phone Country Code: {$countryCode}\n\n" : '';
        $qr_text .= $patient->aadhar_card_num ? "Aadhar Card: {$patient->aadhar_card_num}\n\n" : '';
        $qr_text .= $patient->unique_id ? "Unique ID: {$patient->unique_id}\n\n" : ''; 
           $qr_text .= $patient->abha_number ? "Abha Number: {$patient->abha_number}\n\n" : ''; 
        
        $qr_text .= "--------------------------\n";   

        // Save QR code
        $filename = 'qr_code_' . time();
        $dataUri = $this->qrCodeService->saveQrCode($qr_text, $filename);
        $qrCode = explode('/', $dataUri);
        if (isset($qrCode[1])) {
            $patient->qr_code = $qrCode[1];
        }
      
            
            $patient->save();     
           

        // Step 11: Send activation email
        if ($patient->email) {
            $data = [
                'title' => 'Activation Link',
                'body' => 'This is Bluai Patient Activation Link: ' . url('/activation/' . $patient->patient_id),
            ];
            Mail::to($patient->email)->send(new ActivationPatientMail($data));
        }
        
            return response()->json([
                'success' => true,
                'data' => $response->json()
            ]);
        } else {
            return response()->json([
                'success' => false,
                'error' => $response->body()
            ], $response->status());
        }
    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'error' => 'Exception: ' . $e->getMessage()
        ], 500);
    }
}  



public function verifyAbdmOtpss(Request $request)
{
    // Step 1: Call the ABDM API to verify OTP and get the response
    $url = 'https://bluid.bluai.ai/api/bluid/enrolAbhaByAadhaar';

    // Input data from the request
    $txnId = $request->input('txnId');
    $otpValue = $request->input('otpValue');
    $mobile = $request->input('mobile');
    $accessToken = $request->input('accessToken');
    $publicKeyPem = $request->input('publicKeyPem');

    try {  
        // Make the API call
        $response = Http::timeout(30)->post($url, [
            'txnId' => $txnId,
            'otpValue' => $otpValue,
            'mobile' => $mobile,
            'accessToken' => $accessToken,
            'publicKeyPem' => $publicKeyPem
        ]);

        if (!$response->successful()) {
            return response()->json([
                'success' => false,
                'error' => $response->body()
            ], $response->status());
        }

        // Step 2: Extract the API response data
        $apiData = $response->json()['data']['ABHAProfile'] ?? null;

        if (!$apiData) {
            return response()->json([
                'success' => false,
                'error' => 'No ABHA profile data found in the response'
            ], 400);
        }

        // Step 3: Validation rules
        $rules = [];

    

        // Validate request data
        $validatedData = $request->validate($rules);

        // Step 4: Map API data to patient fields
        $validatedData['first_name'] = $apiData['firstName'] ?? null;
        $validatedData['last_name'] = $apiData['lastName'] ?? null;
        $validatedData['date_of_birth'] = $apiData['dob'] ?? null;
        $validatedData['sex'] = $apiData['gender'] === 'M' ? 'Male' : ($apiData['gender'] === 'F' ? 'Female' : null);
        $validatedData['address'] = $apiData['address'] ?? null;
        $validatedData['patient_phone_number'] = $apiData['mobile'] ?? null;
        $validatedData['email'] = $apiData['email'] ?? null;
        $validatedData['aadhar_card_num'] = str_replace('-', '', $apiData['ABHANumber']) ?? null; // Remove hyphens for numeric validation
        $validatedData['unique_id'] = $apiData['ABHANumber'] ?? null;

        // Step 5: Handle optional fields from request
        $validatedData['disability'] = $request->input('disability');
        if ($validatedData['disability'] === 'other') {
            $validatedData['disability'] = $request->input('other_disability');
        }

        if ($request->has('vaccines')) {
            $validatedData['vaccines'] = json_encode($request->input('vaccines'));
        }

        if ($request->has('blood_group') && !empty($request->blood_group)) {
            $validatedData['blood_group'] = $request->blood_group;
        }

        if ($request->has('organ_donors') && !empty($request->organ_donors)) {
            $validatedData['organ_donors'] = $request->organ_donors;
        }

        // Step 6: Create and fill patient model
        $patient = new Patient();
        $patient->fill($validatedData);

        // Additional fields
        $patient->patient_phone_num_country_code = $request->patient_phone_num_country_code ?? '+91'; // Default to +91 for India
        $patient->email = $validatedData['email'];

        // Step 7: Handle photo from API (base64)
        if (!empty($apiData['photo'])) {
            $fileName = 'photo_' . time() . '.jpg';
            $photoData = base64_decode(preg_replace('#^data:image/\w+;base64,#i', '', $apiData['photo']));
            Storage::disk('public')->put('photos/' . $fileName, $photoData);
            $patient->photo = $fileName;
        }

        // Step 8: Handle file uploads (Aadhaar/SSN cards) if provided in request
        if ($request->hasFile('aadhar_card')) {
            $file = $request->file('aadhar_card');
            $fileName = time() . '_' . $file->getClientOriginalName();
            $file->storeAs('documents', $fileName, 'public');
            $patient->aadhar_card = $fileName;
        }

        if ($request->hasFile('ssn_card')) {
            $file = $request->file('ssn_card');
            $fileName = time() . '_' . $file->getClientOriginalName();
            $file->storeAs('documents', $fileName, 'public');
            $patient->ssn_card = $fileName;
        }

        // Step 9: Generate QR code
        $qr_text = "Patient Information:\n";
        $qr_text .= "--------------------------\n\n";
        $qr_text .= $validatedData['first_name'] ? "First Name: {$validatedData['first_name']}\n\n" : '';
        $qr_text .= $validatedData['last_name'] ? "Last Name: {$validatedData['last_name']}\n\n" : '';
        $qr_text .= $validatedData['date_of_birth'] ? "Date of Birth: {$validatedData['date_of_birth']}\n\n" : '';
        $qr_text .= $validatedData['sex'] ? "Sex: {$validatedData['sex']}\n\n" : '';
        $qr_text .= $validatedData['address'] ? "Address: {$validatedData['address']}\n\n" : '';
        $qr_text .= $validatedData['email'] ? "Email: {$validatedData['email']}\n\n" : '';
        $qr_text .= $patient->patient_phone_num_country_code ? "Phone Country Code: {$patient->patient_phone_num_country_code}\n\n" : '';
        $qr_text .= $validatedData['patient_phone_number'] ? "Phone Number: {$validatedData['patient_phone_number']}\n\n" : '';
        $qr_text .= $validatedData['aadhar_card_num'] ? "Aadhar Card: {$validatedData['aadhar_card_num']}\n\n" : '';
        $qr_text .= $validatedData['blood_group'] ? "Blood Group: {$validatedData['blood_group']}\n\n" : '';
        $qr_text .= $validatedData['organ_donors'] ? "Organ Donors: I am an organ donor\n\n" : '';
        $qr_text .= $validatedData['unique_id'] ? "Unique ID: {$validatedData['unique_id']}\n\n" : '';
        $qr_text .= $validatedData['disability'] ? "Disability: {$validatedData['disability']}\n\n" : '';
        $qr_text .= "--------------------------\n";

        $filename = 'qr_code_' . time();
        $dataUri = $this->qrCodeService->saveQrCode($qr_text, $filename);
        $qrCode = explode('/', $dataUri);
        if (isset($qrCode[1])) {
            $patient->qr_code = $qrCode[1];
        }

        // Step 10: Save the patient
        $patient->save();

        // Step 11: Send activation email
        if ($patient->email) {
            $data = [
                'title' => 'Activation Link',
                'body' => 'This is Bluai Patient Activation Link: ' . url('/activation/' . $patient->patient_id),
            ];
            Mail::to($patient->email)->send(new ActivationPatientMail($data));
        }

        // Step 12: Return success response
        return response()->json([
            'success' => true,
            'message' => 'Patient created successfully',
            'patient_id' => $patient->patient_id
        ], 201);
 
    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'error' => 'Exception: ' . $e->getMessage()
        ], 500);
    }
}  
      
 

    
    public function showPatientPortal()
    {   
       
              $patient = Auth::guard('patients')->user();    
              $data['getNotes'] = Patient::with(['healthHistories' => function($query) {
              $query->orderBy('health_history_id', 'desc'); 
                      }, 'hcpNames'])->find($patient->patient_id);

            return view('patients.patient_notes', $data);
           
    }

   public function patient_portal(Request $request)
{
    $request->validate([
        'phone' => 'required',
        'identifier' => 'required',
    ]);

    try {
        // Find the patient using the correct query
        $patient = Patient::where([
            'patient_phone_number' => $request->phone,
            'aadhar_card_num' => $request->identifier
        ])->first();

        if ($patient) {
            Auth::guard('patients')->login($patient);  
            $patient = Auth::guard('patients')->user(); 

            return response()->json([
                'message' => 'Login successful!',
                'redirect' => route('patients.vitals')
            ]);
        } else {
            return response()->json(['error' => 'Patient not found'], 404);
        }
    } catch (Exception $e) {
        return response()->json(['error' => 'An error occurred: ' . $e->getMessage()], 500);
    }
}
  
    public function sendOTP(Request $request)
    {
    
          
       
        $query = Patient::where(['patient_phone_number' => $request->phone, 'patient_phone_num_country_code' => $request->CountryCode]);

      
         $patient = $query->first();
     
        if (!$patient || $patient === null) {
            return response()->json(['message' => 'Not Registerd, Please Registered As A New patient.', 'status' => true]);
        }
    
        //$otp = rand(100000, 999999);
       // $phone = $patient->patient_phone_num_country_code.''.$request->phone;
       
       // Session::put('otp', $otp);
      //  $this->twilioService->sendOtpViaSms($phone, $otp);
 
        return response()->json(['message' => 'OTP Sent To Message Box!','status' => false]); 
    }


    public function whatappsendOTP(Request $request)
    {
    
        $query = Patient::where(['patient_phone_number', 'patient_phone_num_country_code' => $request->CountryCode]);

        $recordCount = $query->count();
        $patient = '';
        if ($recordCount === 1) {
            $patient = $query->first(); 

        } elseif ($recordCount > 1 ) {

            $patient = $query->where(function ($query) use ($request) {
                $query->where('aadhar_card_num', $request->identifier);
            })->first();

            if(!$request->has('identifier')){ 

            return response()->json(['message' => 'Please Enter Aadhar Card Number', 'status' => true]);
            } 
        } 
     
        if (!$patient || $patient === null) {
            return response()->json(['message' => 'Not Registerd, Please Registered As A New patient.', 'status' => true]);
        }

        $otp = rand(100000, 999999);
        $phone = $patient->patient_phone_num_country_code.''.$request->phone;
        Session::put('otp', $otp);
        $this->twilioService->sendOtp($phone, $otp); 
        return response()->json(['message' => 'OTP Sent To WhatsApp!']); 
    }

    public function verifyOTP(Request $request) 
{
    $inputOTP = $request->otp;
    $sessionOTP = Session::get('otp');

    if ($inputOTP != $sessionOTP || $inputOTP == null) { 
    //    return response()->json(['message' => 'Invalid OTP', 'status' => true]);
   // } else {
        // Identify the patient using phone and country code
        $query = Patient::where([
            'patient_phone_number' => $request->patient_phone_number,
            'patient_phone_num_country_code' => $request->patient_phone_num_country_code
        ]);

        $recordCount = $query->count(); 
       
        $aadharNumbers = [];

    if ($recordCount === 1) {
    $record = $query->first();
    $aadharNumbers[] = [
        'first_name' => $record->first_name,
        'aadhar_card_num' => $record->aadhar_card_num
    ];
} elseif ($recordCount > 1) {
    $aadharNumbers = $query->select('first_name', 'aadhar_card_num')->get()->toArray();
}

return response()->json([
    'message' => 'OTP Verified',
    'status' => true, // Change to true if OTP is verified
    'aadharNumbers' => $aadharNumbers
]);
    }
} 


    public function logout()
{
    
      Auth::guard('patients')->logout(); 

    if (Auth::guard('hcp')->check()) {
        return redirect('/hcp/patients');       
     }else{
   
     return redirect('/patient-login');
    }
}



}
