<?php

use App\Models\EnquiryModel;
use App\Models\QuotationModel;
use App\Models\PolicyModel;
use App\Models\ClientModel;
use App\Models\ClientPolicyModel;
use App\Models\PolicyTransactionModel;
use App\Models\PtCoShareDetailsModel; 
use App\Models\VehicleModel;

if (!function_exists('createBDS')) {
    function createBDS(array $policyData, int $policyId)
    {
        $enquiryModel            = new EnquiryModel();
        $quotationModel          = new QuotationModel();
        $policyModel             = new PolicyModel();
        $clientModel             = new ClientModel();
        $clientPolicyModel       = new ClientPolicyModel();
        $policyTransactionModel  = new PolicyTransactionModel();
        $ptCoShareDetailsModel   = new PtCoShareDetailsModel();
        $vehicleModel            = new VehicleModel();

        $log = []; // collect logs

        // 1. Create or fetch client
        $client = $clientModel->where([
            'client_name' => $policyData['client_name'],
            'phone'       => $policyData['client_mobile'],
            'email'       => $policyData['client_email']
        ])->first();

        if ($client) {
            $clientId = $client['id'];
            $log[] = "Existing client found (ID: {$clientId})";
        } else {
            $clientData = [
                'client_type' => 2,
                'client_name' => $policyData['client_name'],
                'short_name'  => $policyData['client_name'],
                'phone'       => $policyData['client_mobile'],
                'email'       => $policyData['client_email'],
                'created_by'  => $policyData['created_by']
            ];
            $clientId = $clientModel->insert($clientData, true);
            $log[] = "New client created (ID: {$clientId})";
        }

        // 2. Create or fetch client policy
        $clientPolicy = $clientPolicyModel->where([
            'client_id'  => $clientId,
            'policy_id'  => $policyId,
            'policy_no'  => $policyData['policy_number']
        ])->first();

        if ($clientPolicy) {
            $clientPolicyId = $clientPolicy['id'];
            $log[] = "Existing client policy found (ID: {$clientPolicyId})";
        } else {
            $clientPolicyData = [
                'client_id'         => $clientId,
                'policy_id'         => $policyId,
                'policy_type_id'    => 8,
                'insurer_id'        => $policyData['insurer_id'],
                'insurer_branch_id' => $policyData['insurer_branch_id'],
                'policy_start_date' => $policyData['start_date'],
                'policy_end_date'   => $policyData['end_date'],
                'policy_no'         => $policyData['policy_number']
            ];
            $clientPolicyId = $clientPolicyModel->insert($clientPolicyData, true);
            $log[] = "New client policy created (ID: {$clientPolicyId})";
        }

        // 3. Create or fetch vehicle
        $vehicle = $vehicleModel->where([
            'vehicle_no' => $policyData['reg_no'],
            'owner'      => $clientId
        ])->first();

        if ($vehicle) {
            $vehicleId = $vehicle['id'];
            $log[] = "Existing vehicle found (ID: {$vehicleId})";
        } else {
            $vehicleData = [
                'vehicle_no'  => $policyData['reg_no'],
                'type'        => $policyData['vehicle_type_id'],
                'description' => 'Motor Vehicle',
                'owner'       => $clientId,
                'rc'          => $policyData['reg_no'],
                'created_by'  => $policyData['created_by']
            ];
            $vehicleId = $vehicleModel->insert($vehicleData, true);
            $log[] = "New vehicle created (ID: {$vehicleId})";
        }

        // 4. Always create policy transaction
        $policyTransactionData = [
            'issuer'             => 2,
            'issue_type'         => 1,
            'client_id'          => $clientId,
            'policy_type_id'     => 8,
            'client_policy_id'   => $clientPolicyId,
            'insurer_id'         => $policyData['insurer_id'],
            'insurer_branch_id'  => $policyData['insurer_branch_id'],
            'vehicle_id'         => $vehicleId,
            'policy_no'          => $policyData['policy_number'],
            'policy_issue_date'  => $policyData['issued_date'],
            'month'              => $policyData['issued_date'],
            'policy_start_date'  => $policyData['start_date'],
            'policy_end_date'    => $policyData['end_date'],
            'renewal_date'       => (new DateTime($policyData['end_date']))->modify('+1 day')->format('Y-m-d'),
            'endorsement_no'     => null,
            'action_type'        => 'inception',
            'revenue_type'       => "NA",
            'status'             => 'completed',
            'policy_holder_name' => $policyData['insured_name'],
            'ct_type'            => 1,
            'sales_generated_by' => null,
            'serviced_by'        => null,
            'policy_with_corr'   => 0,
            'is_active'          => 1,
            'ref'                => null,
            'co_share'           => 0,
            'endorse_eff_date'   => null,
            'pre_payable_by'     => 1,
            'bro_payable_by'     => 1,
            'agent_id'           => $policyData['agent_id'],
            'agent_code'         => $policyData['agent_code'],
            'pos_id'             => $policyData['pos_id'],
            'entry_from'         => 4,
        ];
        $policyTransactionId = $policyTransactionModel->insert($policyTransactionData, true);
        $log[] = "Policy transaction created (ID: {$policyTransactionId})";

        // 5. Always create pt co-share details
        $ptCoShareDetails = [
            'pt_id'                 => $policyTransactionId,
            'insurer_id'            => $policyData['insurer_id'],
            'insurer_branch_id'     => $policyData['insurer_branch_id'],
            'co_share_type'         => 1,
            'co_share_per'          => 100,
            'pt_policy_issue_date'  => $policyData['issued_date'],
            'bp_amt'                => $policyData['od'],
            'cop_amt'               => $policyData['od'],
            'exp_amt'               => $policyData['commission_amount'], 
            'agreed_amt'            => $policyData['commission_amount'], 
           'bp_igst' => !empty($policyData['premium_amount']) 
                ? ($policyData['igst'] / $policyData['premium_amount']) * 100 
                : 0,
            'bp_cgst' => !empty($policyData['premium_amount']) 
                ? ($policyData['cgst'] / $policyData['premium_amount']) * 100 
                : 0,
            'bp_sgst' => !empty($policyData['premium_amount']) 
                ? ($policyData['sgst'] / $policyData['premium_amount']) * 100 
                : 0,
            'tp_amt'  =>  $policyData['tp'],
            'cotp_amt'=>  $policyData['tp'],
            'bp_gst_amt'  => ($policyData['sgst']+$policyData['cgst']+$policyData['igst']),
            'amount' => $policyData['premium_amount'],
        ];
        $ptCoShareId = $ptCoShareDetailsModel->insert($ptCoShareDetails, true);
        $log[] = "PT Co-Share details created (ID: {$ptCoShareId})";

        // 6. Update policy with IDs
        $policyModel->update($policyId, [
            'client_id'             => $clientId,
            'client_policy_id'      => $clientPolicyId,
            'vehicle_id'            => $vehicleId,
            'policy_transaction_id' => $policyTransactionId,
            'pt_oc_share_details_id'=> $ptCoShareId,
            'updated_by'            => $policyData['created_by'],
            'updated_on'            => date('Y-m-d H:i:s')
        ]);
        $log[] = "Policy updated with references (Policy ID: {$policyId})";

        return $log; // return logs for debugging
    }

}


if (!function_exists('format_date_for_database')) {

    function format_date_for_database(?string $date): ?string
    {
        if (empty($date)) return null;  // ✅ handle null/empty
        $dt = DateTime::createFromFormat('d-m-Y', $date);
        if ($dt) {
            return $dt->format('Y-m-d');
        }

        return null;
    }
}

if (!function_exists('format_date_for_client')) {

    function format_date_for_client(string $date): ?string
    {
        $dt = DateTime::createFromFormat('Y-m-d', $date);
        if ($dt) {
            return $dt->format('d-m-Y');
        }

        return null;
    }
}


if (!function_exists('generate_uuid')) {
    function generate_uuid($version = 4, $format = 'hex')
    {
        $data = random_bytes(16);
        // Set version to 0100
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
        // Set bits 6-7 to 10
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
        // Output the 36 character UUID.
        $uuid = vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
        return $uuid;
    }
}
