<?php

namespace App\Controllers;

use App\Models\EndorsementModel;
use App\Models\PolicyModel;
use App\Models\EnquiryModel;
use App\Models\QuotationModel;
use App\Models\StaffModel;
use CodeIgniter\RESTful\ResourceController;

class EndorsementController extends ResourceController
{
    protected $db;
    protected $EndorsementModel;
    protected $PolicyModel;
    protected $QuotationModel;
    protected $EnquiryModel;
    protected $StaffModel;

    public function __construct()
    {
        $this->db = db_connect();
        $this->EndorsementModel = new EndorsementModel();
        $this->PolicyModel = new PolicyModel();
        $this->QuotationModel = new QuotationModel();
        $this->EnquiryModel = new EnquiryModel();
        $this->StaffModel = new StaffModel();
    }


    public function EndorsementList()
    {
        try {
            $id         = $this->request->getGet('id');         // endorsement id
            $manager_id = $this->request->getGet('manager_id');
            $agent_id   = $this->request->getGet('agent_id');
            $policy_number   = $this->request->getGet('policy_number');

            $from_date          = $this->request->getGet('from_date');
            $to_date            = $this->request->getGet('to_date');
            $endorsement_type   = $this->request->getGet('endorsement_type');
            $insurer_id         = $this->request->getGet('insurer_id');
            $status             = $this->request->getGet('status');
            $verification       = $this->request->getGet('verification');
            $search             = $this->request->getGet('search');

            $builder = $this->EndorsementModel
                ->select('partner_endorsement_request.*, 
                            CASE 
                                WHEN partner_endorsement_request.policy_start_date = "0000-00-00"
                                OR YEAR(partner_endorsement_request.policy_start_date) < 2000 
                                THEN NULL 
                                ELSE DATE_FORMAT(partner_endorsement_request.policy_start_date, "%Y-%m-%d") 
                            END as policy_start_date,
                            CASE 
                                WHEN partner_endorsement_request.policy_end_date = "0000-00-00"
                                OR YEAR(partner_endorsement_request.policy_end_date) < 2000 
                                THEN NULL 
                                ELSE DATE_FORMAT(partner_endorsement_request.policy_end_date, "%Y-%m-%d") 
                            END as policy_end_date,
                          i.name as insurer_name,
                          i.short_name as insurer_short_name,
                          ib.branch_name as insurer_branch,
                          c.client_name, c.phone as client_phone, c.email as client_email,
                          partner_endorsement_request.agent_id,
                          pa.agent_code as agent_code,
                          pa.name as agent_name,
                          pp.enquiry_id,
                          etm.endorsement_type as endorsement_type_value,
                          PB.name as broker_name,
                          pm.value as payment_mode_value')
                ->join('insurers i', 'i.id = partner_endorsement_request.insurer_id', 'left')
                ->join('insurer_branch ib', 'ib.id = partner_endorsement_request.insurer_branch_id', 'left')
                ->join('clients c', 'c.id = partner_endorsement_request.client_id', 'left')
                ->join('partner_agent pa', 'pa.id = partner_endorsement_request.agent_id', 'left')
                ->join('partner_policy pp', 'pp.policy_number = partner_endorsement_request.policy_number', 'left')
                ->join('partner_enquiry pe', 'pe.id = pp.enquiry_id', 'left')
                ->join('partner_endorsement_type_master etm', 'etm.id = partner_endorsement_request.endorsement_type', 'left')
                ->join('partner_brokers PB', 'PB.id = partner_endorsement_request.broker_id', 'left')
                ->join('partner_payment_mode_master pm', 'pm.id = partner_endorsement_request.payment_mode_id', 'left')
                ->where('partner_endorsement_request.is_active', 1);

            // If ID is provided, fetch single record
            if (!empty($id)) {
                $builder->where('partner_endorsement_request.id', $id);
                $record = $builder->get()->getRowArray();

                if (!$record) {
                    return $this->respond(['status' => 'failed','code'   => 404,'data'   => 'Not Found'], 404);
                }

                return $this->respond(['status' => 'success','code'   => 200,'data'   => $record ], 200);
            }

            // Apply filters
            if (!empty($manager_id)) {
                $builder->where('partner_endorsement_request.manager_id', $manager_id);
            }

            if (!empty($agent_id)) {
                $builder->where('partner_endorsement_request.agent_id', $agent_id);
            }

            if (!empty($policy_number)) {
                $builder->where('partner_endorsement_request.policy_number', $policy_number);
            }

            if (!empty($from_date) && !empty($to_date)) {
                $builder->where('partner_endorsement_request.created_at >=', $from_date . ' 00:00:00')
                        ->where('partner_endorsement_request.created_at <=', $to_date . ' 23:59:59');
            }

            if (!empty($endorsement_type) && $endorsement_type != 'All') {
                $builder->where('partner_endorsement_request.endorsement_type', $endorsement_type);
            }

            if (!empty($insurer_id)) {
                $builder->where('partner_endorsement_request.insurer_id', $insurer_id);
            }

            if (!empty($status) && $status != 'All') {
                $builder->where('partner_endorsement_request.status', $status);
            }

            if (!empty($verification) && $verification != 'All') {

                if ($verification == 'Verified') {
                    $builder->where('partner_endorsement_request.is_data_accuracy_checked', 1);
                } elseif ($verification == 'To Verify') {
                    $builder->where('partner_endorsement_request.is_data_accuracy_checked', 0);
                }
            }



            $data = $builder->get()->getResultArray();

            foreach ($data as $key => $row) {
                $data[$key]['created_at']  = date('d-m-Y h:i A', strtotime($row['created_at']));
                $data[$key]['updated_at']  = date('d-m-Y h:i A', strtotime($row['updated_at']));
                 // ✅ NULL-safe date formatting
                $data[$key]['policy_start_date'] = (!empty($row['policy_start_date']) && $row['policy_start_date'] !== '0000-00-00')
                    ? date('d-m-Y', strtotime($row['policy_start_date']))
                    : null;

                $data[$key]['policy_end_date'] = (!empty($row['policy_end_date']) && $row['policy_end_date'] !== '0000-00-00')
                    ? date('d-m-Y', strtotime($row['policy_end_date']))
                    : null;
            }

            return $this->respond(['status' => 'success','code'   => 200,'data'   => $data], 200);
        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed','code'   => 500,'data'   => $e->getMessage()], 500);
        }
    }


    public function createEndorsement()
    {
        try {

            $reqData = $this->request->getPost();

            // Basic validation
            if (empty($reqData['policy_from']) || empty($reqData['policy_number']) || empty($reqData['endorsement_type']) ) 
            {
                return $this->respond(['status' => 'failed','code'   => 400,'data'   => 'policy_from, policy_number, endorsement_type are required' ], 400);
            }

            $policy = null;

            // INTERNAL POLICY FLOW
            if ($reqData['policy_from'] === 'Internal') {

                $policy = $this->PolicyModel
                    ->select('partner_policy.*, 
                            Q.insurer_id, Q.insurer_branch_id, Q.payment_mode_id,
                            E.name as insured_name,
                            E.mobile as client_mobile,
                            E.email as client_email,
                            E.reg_no,
                            E.broker_id')
                    ->join('partner_quotation Q', 'Q.id = partner_policy.quotation_id AND Q.status = "Accepted"', 'left')
                    ->join('partner_enquiry E', 'E.id = partner_policy.enquiry_id', 'left')
                    ->where('partner_policy.policy_number', $reqData['policy_number'])
                    ->first();

                if (empty($policy)) {
                    return $this->respond(['status' => 'failed','code'   => 404,'data'   => 'Internal policy not found'], 404);
                }
            }

            //FILE UPLOAD
            $uploadedFileName = null;
            $uploadFile = $this->request->getFile('endorsement_file_name');

            if ($uploadFile && $uploadFile->isValid()) {

                $uploadPath = WRITEPATH . 'uploads/endorsement/';
                if (!is_dir($uploadPath)) {
                    mkdir($uploadPath, 0777, true);
                }

                $uploadedFileName = time() . '_' . $uploadFile->getRandomName();
                $uploadFile->move($uploadPath, $uploadedFileName);
            }

            // PREPARE DATA
            if ($reqData['policy_from'] === 'Internal') {

                // Take values from DB
                $endorsementData = [
                    'policy_from'            => 'Internal',
                    'policy_number'          => $policy['policy_number'],
                    'client_policy_id'       => $policy['client_policy_id'] ?? null,
                    'insurer_id'             => $policy['insurer_id'] ?? null,
                    'insurer_branch_id'      => $policy['insurer_branch_id'] ?? null,
                    'policy_start_date'      => $policy['start_date'] ?? null,
                    'policy_end_date'        => $policy['end_date'] ?? null,
                    'reg_no'                 => $policy['reg_no'] ?? null,
                    'broker_id'              => $policy['broker_id'] ?? null,
                    'insured_name'           => $policy['insured_name'] ?? null,
                    'payment_mode_id'        => $policy['payment_mode_id'] ?? null,
                ];

            } else {

                // use values from Request
                $endorsementData = [
                    'policy_from'       => 'External',
                    'policy_number'     => $reqData['policy_number'],
                    'insurer_id'        => $reqData['insurer_id'] ?? null,
                    'insurer_branch_id' => $reqData['insurer_branch_id'] ?? null,
                    'policy_start_date' => format_date_for_database($reqData['policy_start_date'] ?? null),
                    'policy_end_date'   => format_date_for_database($reqData['policy_end_date'] ?? null),
                    'reg_no'            => $reqData['reg_no'] ?? null,
                    'broker_id'         => $reqData['broker_id'] ?? null,
                    'insured_name'      => $reqData['insured_name'] ?? null,
                    'payment_mode_id'   => $reqData['payment_mode_id'] ?? null,
                ];
            }

            // Common fields
            $endorsementData += [
                'manager_id'                => $reqData['manager_id'] ?? null,
                'agent_id'                  => $reqData['agent_id'] ?? null,
                'endorsement_type'          => $reqData['endorsement_type'],
                'endorsement_description'   => $reqData['endorsement_description'],
                'endorsement_no'            => $reqData['endorsement_no'] ?? null,
                'contact_person'            => $reqData['contact_person'] ?? null,
                'pending_days'              => $reqData['pending_days'] ?? null,
                'financia_or_non_financial' => $reqData['financia_or_non_financial'] ?? null,
                'endorsement_premium'       => $reqData['endorsement_premium'] ?? null,
                'commission_amount'         => $reqData['commission_amount'] ?? null,
                'created_by'                => $reqData['created_by'] ?? null,
                'status'                    => 'Open',
                'endorsement_file_name'     => $uploadedFileName,
                'is_active'                 => 1
            ];

            if (!$this->EndorsementModel->insert($endorsementData))
            {
                return $this->respond(['status' => 'failed','code'   => 422, 'data'   => $this->EndorsementModel->errors() ], 422);
            }

            return $this->respond(['status' => 'success','code'   => 200,'data'   => ['endorsement_id' => $this->EndorsementModel->getInsertID()]], 200);

        } catch (\Exception $e) {

            return $this->respond(['status' => 'failed','code'   => 500,'data'   => $e->getMessage()], 500);
        }
    }

    public function updateEndorsement()
    {
        try {

            $endorsementId = $this->request->getPost('id');

            if (!$endorsementId) { return $this->respond(['status' => 'failed', 'code'   => 400, 'data'   => 'id is required'], 400);}

            $reqData = $this->request->getPost();

            // Fetch existing record
            $endorsement = $this->EndorsementModel->find((int)$endorsementId);

            if (!$endorsement) { return $this->respond([ 'status' => 'failed', 'code'   => 404,'data'   => 'Endorsement not found'  ], 404); }

            // FILE UPLOAD 
            $uploadedOriginalCompletionFile = $endorsement['endorsement_file_name'];

            $uploadOriginalFile = $this->request->getFile('endorsement_file_name');

            if ($uploadOriginalFile && $uploadOriginalFile->isValid()) {

                $uploadOriginalPath = WRITEPATH . 'uploads/endorsement/';
                if (!is_dir($uploadOriginalPath)) {
                    mkdir($uploadOriginalPath, 0777, true);
                }

                $uploadedOriginalCompletionFile = time() . '_' . $uploadOriginalFile->getRandomName();
                $uploadOriginalFile->move($uploadOriginalPath, $uploadedOriginalCompletionFile); // ✅ fixed variable
            }

            // FILE REVISED UPLOAD
            $uploadedRevisedCompletionFile = $endorsement['endorsement_completion_file'];
            $uploadRevisedFile = $this->request->getFile('endorsement_completion_file');

            if ($uploadRevisedFile && $uploadRevisedFile->isValid()) {
                $uploadRevisedPath = WRITEPATH . 'uploads/endorsement/endorsement_pdf/';
                if (!is_dir($uploadRevisedPath)) {
                    mkdir($uploadRevisedPath, 0777, true);
                }
                $uploadedRevisedCompletionFile = time() . '_' . $uploadRevisedFile->getRandomName();
                $uploadRevisedFile->move($uploadRevisedPath, $uploadedRevisedCompletionFile);
            }

            /*
             * COMMON UPDATE FIELDS
             * Keep update mapping explicit so fields sent by frontend are not silently ignored.
             */

            $updateData = [];

            // Update only if provided (avoid null overwrite)
            if (isset($reqData['policy_from'])) {
                $updateData['policy_from'] = $reqData['policy_from'];
            }

            if (isset($reqData['policy_number'])) {
                $updateData['policy_number'] = $reqData['policy_number'];
            }

            if (isset($reqData['manager_id'])) {
                $updateData['manager_id'] = $reqData['manager_id'];
            }

            if (isset($reqData['agent_id'])) {
                $updateData['agent_id'] = $reqData['agent_id'];
            }

            if (isset($reqData['endorsement_type'])) {
                $updateData['endorsement_type'] = $reqData['endorsement_type'];
            }

            if (isset($reqData['endorsement_description'])) {
                $updateData['endorsement_description'] = $reqData['endorsement_description'];
            }

            if (isset($reqData['endorsement_no'])) {
                $updateData['endorsement_no'] = $reqData['endorsement_no'];
            }

            if (isset($reqData['status'])) {
                $updateData['status'] = $reqData['status'];
            }

            if (isset($reqData['contact_person'])) {
                $updateData['contact_person'] = $reqData['contact_person'];
            }

            if (isset($reqData['financia_or_non_financial'])) {
                $updateData['financia_or_non_financial'] = $reqData['financia_or_non_financial'];
            }

            if (isset($reqData['endorsement_premium'])) {
                $updateData['endorsement_premium'] = $reqData['endorsement_premium'];
            }

            if (isset($reqData['commission_amount'])) {
                $updateData['commission_amount'] = $reqData['commission_amount'];
            }

            if (isset($reqData['pending_days'])) {
                $updateData['pending_days'] = $reqData['pending_days'];
            }

                       
            // Always update both files (new or existing)
            $updateData['endorsement_file_name']        = $uploadedOriginalCompletionFile;
            $updateData['endorsement_completion_file']  = $uploadedRevisedCompletionFile; // ✅ fixed variable

            /*
             * External Policy Editable Fields
             * Use incoming policy_from first (if provided), fallback to stored value.
             * This prevents missing updates when stored value casing differs (external/External).
             */
            $effectivePolicyFrom = $reqData['policy_from'] ?? $endorsement['policy_from'] ?? '';
            if (strcasecmp(trim((string)$effectivePolicyFrom), 'External') === 0) {

                if (isset($reqData['insurer_id'])) {
                    $updateData['insurer_id'] = $reqData['insurer_id'] ?? null;
                }

                if (isset($reqData['insurer_branch_id'])) {
                    $updateData['insurer_branch_id'] = $reqData['insurer_branch_id'] ?? null;
                }

                if (isset($reqData['policy_start_date'])) {
                    $updateData['policy_start_date'] = format_date_for_database($reqData['policy_start_date'] ?? null);
                }

                if (isset($reqData['policy_end_date'])) {
                    $updateData['policy_end_date'] = format_date_for_database($reqData['policy_end_date'] ?? null);
                }

                if (isset($reqData['insured_name'])) {
                    $updateData['insured_name'] = $reqData['insured_name'] ?? null;
                }

                if (isset($reqData['reg_no'])) {
                    $updateData['reg_no'] = $reqData['reg_no'] ?? null;
                }

                if (isset($reqData['broker_id'])) {
                    $updateData['broker_id'] = $reqData['broker_id'] ?? null;
                }

                if (isset($reqData['payment_mode_id'])) {
                    $updateData['payment_mode_id'] = $reqData['payment_mode_id'];
                }
            }

            $updateData['updated_by'] = $reqData['updated_by'] ?? null;

            if (!empty($updateData['updated_by'])) {

                $staff = $this->StaffModel
                                ->select('role_id')
                                ->where('id', $updateData['updated_by'])
                                ->first();

                if (!empty($staff) && $staff['role_id'] == 4) {
                    $updateData['is_data_accuracy_checked'] = 1;
                    $updateData['status'] = "Closed" ;
                }
            }

            /**
             * ===========================
             * UPDATE
             * ===========================
             */

            if (!$this->EndorsementModel->update($endorsementId, $updateData)) {
                return $this->respond([
                    'status' => 'failed',
                    'code'   => 422,
                    'data'   => $this->EndorsementModel->errors()
                ], 422);
            }

            return $this->respond([
                'status' => 'success',
                'code'   => 200,
                'data'   => [
                    'endorsement_id' => $endorsementId,
                    'message'        => 'Endorsement updated successfully'
                ]
            ], 200);

        } catch (\Exception $e) {

            return $this->respond([
                'status' => 'failed',
                'code'   => 500,
                'data'   => $e->getMessage()
            ], 500);
        }
    }

    public function deleteEndorsement()
    {
        try {

            $id = $this->request->getGet('id');

          
            // check if EndorsementModel exists
            $file = $this->EndorsementModel->find((int)$id);
            if (!$file) {
                return $this->respond(['status' => 'failed','code'   => 200, 'data'   => 'Endorsement not found'], 200);
            }

            // update status
            $this->EndorsementModel->update($id, ['is_active' => 0]);

            return $this->respond([
                'status'  => 'success', 'code'    => 200,'data'   => "Endorsement Deleted"], 200);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed','code'   => 500,'data'   => $e->getMessage()], 500);
        }
    }


    // public function createEndorsement()
    // {
    //     try {
    //         $reqData = $this->request->getPost();

    //         // Validate required fields
    //         if (empty($reqData['policy_number']) || empty($reqData['endorsement_type']) || empty($reqData['endorsement_description'])) {
    //             return $this->respond(['status' => 'failed','code'   => 400,'data'   => 'policy_number, endorsement_type and endorsement_description are required' ], 200);
    //         }

    //         // Fetch policy details
    //         $policy = $this->PolicyModel->select('partner_policy.*, Q.insurer_id, Q.insurer_branch_id, E.name as client_name, E.mobile as client_mobile, E.email as client_email, E.reg_no, E.broker_id')
    //                                     ->join('partner_quotation Q', 'Q.id = partner_policy.quotation_id AND Q.status = "Accepted"', 'left')
    //                                     ->join('partner_enquiry E', 'E.id = partner_policy.enquiry_id', 'left')
    //                                     ->where('partner_policy.policy_number', $reqData['policy_number'])
    //                                     ->first();

    //         if (empty($policy) && $reqData['policy_from'] == 'Internal') {
    //             return $this->respond(['status' => 'failed','code'   => 404,'data'   => 'Policy not found'], 200);
    //         }


    //         $uploadFile = $this->request->getFile('endorsement_file_name');
    //         $uploadedFileName = null;

    //         if ($uploadFile && $uploadFile->isValid()) {
    //             $uploadPath = WRITEPATH . 'uploads/endorsement/';
    //             if (!is_dir($uploadPath)) {
    //                 mkdir($uploadPath, 0777, true);
    //             }
    //             $uploadedFileName = time() . '_' . $uploadFile->getRandomName();
    //             $uploadFile->move($uploadPath, $uploadedFileName);
    //         }

    //         //  Prepare endorsement data
    //         $endorsementData = [
    //             'policy_from'            => $reqData['policy_from'],
    //             'policy_number'          => $policy['policy_number'] ?? $reqData['policy_number'],
    //             'client_policy_id'       => $policy['client_policy_id'] ?? null,
    //             'insurer_id'             => $policy['insurer_id'] ?? null,
    //             'insurer_branch_id'      => $policy['insurer_branch_id'] ?? null,
    //             'client_id'              => $policy['client_id'] ?? null,
    //             'agent_id'               => $policy['agent_id'] ?? null,
    //             'policy_start_date'      => $policy['start_date'] ?? null,
    //             'policy_end_date'        => $policy['end_date'] ?? null,
    //             'reg_no'                 => $policy['reg_no'] ?? null,
    //             'broker_id'              => $policy['broker_id'] ?? null,
    //             'insured_name'           => $policy['insured_name'] ?? null,
    //             'commission_amount'      => $reqData['agent_id'] ?? null,
    //             'manager_id'             => $reqData['manager_id'] ?? null,
    //             'endorsement_type'       => $reqData['endorsement_type'],
    //             'endorsement_description'=> $reqData['endorsement_description'],
    //             'endorsement_no'         => $reqData['endorsement_no'] ?? null,
    //             'created_by'             => $reqData['created_by'] ?? null,
    //             'status'                 => 'Open',
    //             'endorsement_file_name'  => $uploadedFileName,
    //             'is_active'              => 1
    //         ];


    //         if (!$this->EndorsementModel->insert($endorsementData)) {
    //             return $this->respond([ 'status' => 'failed', 'code'   => 422, 'data'   => $this->EndorsementModel->errors()], 422);
    //         }

    //         return $this->respond([ 'status' => 'success', 'code'   => 200, 'data'   => ['endorsement_id' => $this->EndorsementModel->getInsertID()] ], 200);

    //     } catch (\Exception $e) {
    //         return $this->respond([ 'status' => 'failed', 'code'   => 500, 'data'   => $e->getMessage() ], 500);
    //     }
    // }

    // public function updateEndorsement()
    // {
    //     try {

    //         $endorsementId = $this->request->getPost('id');

    //         if (!$endorsementId) {
    //             return $this->respond([ 'status' => 'failed', 'code'   => 400, 'data'   => 'endorsementId is required' ], 200);
    //         }

    //         $reqData = $this->request->getPost();

    //         // Fetch existing record
    //         $endorsement = $this->EndorsementModel->find((int)$endorsementId);

    //         if (empty($endorsement)) {
    //             return $this->respond([ 'status' => 'failed', 'code'   => 404, 'data'   => 'Endorsement not found' ], 200);
    //         }

    //         // Handle upload (endorsement completion file)
    //         $uploadFile = $this->request->getFile('endorsement_completion_file');
    //         $uploadedCompletionFile = $endorsement['endorsement_completion_file']; // keep old if not replaced

    //         if ($uploadFile && $uploadFile->isValid()) {

    //             $uploadPath = WRITEPATH . 'uploads/endorsement/';
    //             if (!is_dir($uploadPath)) {
    //                 mkdir($uploadPath, 0777, true);
    //             }

    //             $uploadedCompletionFile = time() . '_' . $uploadFile->getRandomName();
    //             $uploadFile->move($uploadPath, $uploadedCompletionFile);
    //         }

    //         // Prepare data to update
    //         $updateData = [
    //             'endorsement_type'              => $reqData['endorsement_type'] ?? $endorsement['endorsement_type'],
    //             'endorsement_description'       => $reqData['endorsement_description'] ?? $endorsement['endorsement_description'],
    //             'endorsement_no'                => $reqData['endorsement_no'] ?? $endorsement['endorsement_no'],
    //             'status'                        => $reqData['status'] ,
    //             'endorsement_completion_file'   => $uploadedCompletionFile,
    //             'contact_person'                => $reqData['contact_person'] ,
    //             'financia_or_non_financial'     => $reqData['financia_or_non_financial'] ,
    //             'endorsement_premium'           => $reqData['endorsement_premium'] ,
    //             'pending_days'                  => $reqData['pending_days'] ,
    //             'updated_by'                    => $reqData['updated_by'] ?? null,
    //         ];

    //         if (!$this->EndorsementModel->update($endorsementId, $updateData)) {
    //             return $this->respond([
    //                 'status' => 'failed',
    //                 'code'   => 422,
    //                 'data'   => $this->EndorsementModel->errors()
    //             ], 422);
    //         }

    //         return $this->respond([
    //             'status' => 'success',
    //             'code'   => 200,
    //             'data'   => ['endorsement_id' => $endorsementId, 'message' => 'Endorsement updated successfully']
    //         ], 200);

    //     } catch (\Exception $e) {
    //         return $this->respond([
    //             'status' => 'failed',
    //             'code'   => 500,
    //             'data'   => $e->getMessage()
    //         ], 500);
    //     }
    // }


    public function downloadEndorsementCompletionFile()
    {
        try {
            $id = $this->request->getGet('id');
            $type = $this->request->getGet('type'); // 'completion' or 'original'

            if (!$id) {
                return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'ID is required'], 200);
            }

            // Fetch record from DB
            $fileRecord = $this->EndorsementModel->find((int)$id);

            if (!$fileRecord) {
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File not found'], 200);
            }

            // $filePath = WRITEPATH . 'uploads/endorsement/' . $fileRecord['endorsement_file_name'];
            
            // ✅ If type is null/empty → original (default)
            // ✅ If type = 'completion' → endorsement_pdf/ subfolder
            if (!$type || $type === 'original') {
                $fileName = $fileRecord['endorsement_file_name'] ?? null;
                $subPath  = '';
            } else if ($type === 'completion') {
                $fileName = $fileRecord['endorsement_completion_file'] ?? null;
                $subPath  = 'endorsement_pdf/';
            }

            if (!$fileName) {
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'No file uploaded yet'], 200);
            }

            $filePath = WRITEPATH . 'uploads/endorsement/' . $subPath . $fileName;

            if (!file_exists($filePath)) {
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File missing on server'], 200);
            }

            // Force file download
            return $this->response->download($filePath, null);

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $e->getMessage()], 500);
        }
    }

    public function EndorsementFilePathGOWTHAM()
    {
        try {
            $endorsementId = $this->request->getGet('endorsement_id');

            if (!$endorsementId) {
                return $this->respond(['status' => 'failed','code'   => 400,'data'   => 'endorsement_id is required'], 200);
            }

            // Fetch record from DB
            $fileRecord = $this->EndorsementModel->where('is_active', 1)->find((int)$endorsementId);

            if (!$fileRecord || empty($fileRecord['endorsement_file_name'])) {
                return $this->respond([ 'status' => 'failed','code'   => 404,'data'   => 'File not found in database'], 200);
            }

            $filePath = WRITEPATH . "uploads/endorsement/" . $fileRecord['endorsement_file_name'];
            $publicUrl = base_url("uploads/endorsement/" . $fileRecord['endorsement_file_name']);

            if (!file_exists($filePath)) {
                return $this->respond(['status' => 'failed','code'   => 404,'data'   => 'File missing on server'], 200);
            }

            
            // return $this->respond(['status' => 'success', 'code' => 200, 'data' => $publicUrl ], 200);

            // Detect the file mime type
            $mime = mime_content_type($filePath);

            // Stream file to browser / Flutter
            return $this->response
                ->setHeader('Content-Type', $mime)
                ->setHeader('Content-Disposition', 'inline; filename="' . $fileRecord['endorsement_file_name'] . '"')
                ->setBody(file_get_contents($filePath));


        } catch (\Exception $e) {
            return $this->respond(['status'  => 'failed','code'    => 500,'message' => $e->getMessage() ], 500);
        }
    }

    public function EndorsementFilePath()
    {
        try {
            $endorsementId = $this->request->getGet('endorsement_id');
            
            if (!$endorsementId) {
                return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'endorsement_id is required'], 200);
            }

            // Fetch record from DB
            $fileRecord = $this->EndorsementModel->where('is_active', 1)->find((int)$endorsementId);

            if (!$fileRecord) {
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File not found in database'], 200);
            }

            // ✅ STEP 1: Check completion file first
            $completionFile = $fileRecord['endorsement_completion_file'] ?? null;
            $originalFile   = $fileRecord['endorsement_file_name'] ?? null;

            if (!empty($completionFile)) {
                // ✅ Use completion file path
                $fileName = $completionFile;
                $filePath = WRITEPATH . 'uploads/endorsement/endorsement_pdf/' . $fileName;
            } elseif (!empty($originalFile)) {
                // ✅ Fallback to original file path
                $fileName = $originalFile;
                $filePath = WRITEPATH . 'uploads/endorsement/' . $fileName;
            } else {
                // ❌ Neither file exists in DB
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'No file uploaded yet'], 200);
            }

            // ✅ STEP 2: Check file exists on disk
            if (!file_exists($filePath)) {
                return $this->respond(['status' => 'failed', 'code' => 404, 'data' => 'File missing on server'], 200);
            }

            // ✅ STEP 3: Stream file to browser / Flutter
            $mime = mime_content_type($filePath);

            return $this->response
                ->setHeader('Content-Type', $mime)
                ->setHeader('Content-Disposition', 'inline; filename="' . $fileName . '"')
                ->setBody(file_get_contents($filePath));

        } catch (\Exception $e) {
            return $this->respond(['status' => 'failed', 'code' => 500, 'message' => $e->getMessage()], 500);
        }
    }

    public function uploadEndorsementFile()
    {
        try {
            $data = $this->request->getPost();

            // ✅ Validate required POST fields first
            if (empty($data['id']) || empty($data['updated_by'])) {
                return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Missing required fields'], 400);
            }

            $uploadPath   = WRITEPATH . 'uploads/endorsement/';
            $allowedTypes = ['application/pdf'];
            $pdfPath      = $uploadPath . 'endorsement_pdf/';

            $endorsementPdf = $this->request->getFile('endorsement_completion_file');

            // ✅ Check file existence and validity BEFORE accessing its properties
            if (!$endorsementPdf || !$endorsementPdf->isValid()) {
                return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'No valid file received'], 400);
            }

            // ✅ MIME validation only after confirming file exists
            if (!in_array($endorsementPdf->getMimeType(), $allowedTypes)) {
                return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'Only PDF files are allowed'], 400);
            }

            // ✅ Fetch existing record to get old file name BEFORE uploading
            $existingRecord = $this->EndorsementModel->find($data['id']);
            $oldFileName    = $existingRecord['endorsement_completion_file'] ?? null;

            // ✅ Ensure upload directory exists
            if (!is_dir($pdfPath)) {
                mkdir($pdfPath, 0777, true);
            }

            // ✅ Upload new file
            $pdfFileName = time() . '_' . $endorsementPdf->getRandomName();
            $endorsementPdf->move($pdfPath, $pdfFileName);

            // ✅ Guard: ensure file was actually saved on disk
            if (!$pdfFileName || !file_exists($pdfPath . $pdfFileName)) {
                return $this->respond(['status' => 'failed', 'code' => 400, 'data' => 'File upload failed'], 400);
            }

            // ✅ Update DB with new file name
            $updateData = [
                'endorsement_completion_file' => $pdfFileName,
                'updated_by'                  => $data['updated_by'],
            ];

            $updated = $this->EndorsementModel->update($data['id'], $updateData);

            // ✅ DB update failed → delete the newly uploaded file to avoid orphan files
            if (!$updated) {
                if (file_exists($pdfPath . $pdfFileName)) {
                    unlink($pdfPath . $pdfFileName);
                }
                log_message('error', 'DB update failed for endorsement ID: ' . $data['id'] . '. New file removed.');
                return $this->respond(['status' => 'failed', 'code' => 500, 'data' => 'DB update failed, file not saved'], 500);
            }

            // ✅ DB success → NOW safe to delete old file
            if ($oldFileName) {
                $oldFilePath = $pdfPath . $oldFileName;
                if (file_exists($oldFilePath)) {
                    if (!unlink($oldFilePath)) {
                        log_message('warning', 'DB updated but failed to delete old file: ' . $oldFilePath);
                    } else {
                        log_message('info', 'Old file deleted after successful DB update: ' . $oldFilePath);
                    }
                }
            }

            log_message('info', 'Endorsement PDF uploaded successfully. ID: ' . $data['id'] . ', File: ' . $pdfFileName);

            return $this->respond(['status' => 'success', 'code' => 200, 'data' => $data['id']], 200);

        } catch (\Exception $e) {
            log_message('error', 'uploadEndorsementFile error: ' . $e->getMessage());
            return $this->respond(['status' => 'failed', 'code' => 500, 'data' => $e->getMessage()], 500);
        }
    }

}
