<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\LeaveCredit;
use App\Models\EmployeeMaster;
use App\Models\Department;
use App\Models\DesignationMaster;
use App\Models\PayrollBill;
use App\Models\LeaveTypeMaster;
use App\Models\EmployeeStatusMaster;
use App\Models\EmpTypeMaster;
use App\Models\DocumentLibrary;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;

class LeaveCreditController extends Controller
{
    /**
     * Display a listing of the resource (paginated)
     */
    public function index()
    {
        try {
            $leaveCredits = LeaveCredit::with(['leaveType', 'payrollBill', 'employeeStatus', 'employeeType', 'action'])
                ->orderBy('created_at', 'desc')
                ->paginate(20);

            return response()->json([
                'success' => true,
                'data' => $leaveCredits
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch leave credits',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get all leave credits without pagination
     */
    public function all()
    {
        try {
            $leaveCredits = LeaveCredit::with(['leaveType', 'payrollBill', 'employeeStatus', 'employeeType', 'action'])
                ->orderBy('created_at', 'desc')
                ->get();

            return response()->json([
                'success' => true,
                'data' => $leaveCredits
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch leave credits',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get filter options with employee status and type
     */
    public function getFilterOptions()
    {
        try {
            $departments = Department::active()->allData()->get(['Dpt_id', 'Dpt_Name', 'Dpt_Desc']);
            $designations = DesignationMaster::active()->get(['Dsg_id', 'Dsg_Title', 'Dsg_Desc']);
            $payrollBills = PayrollBill::all(['PRB_id', 'PayBill_Code', 'Description']);
            $leaveTypes = LeaveTypeMaster::where('Is_Active', 1)->get(['LT_id', 'LT_code', 'LT_name', 'Max_days', 'Acr_Plcy']);
            $employeeStatuses = EmployeeStatusMaster::where('Is_Active', 1)->get(['Est_Id', 'Est_Code', 'Est_Name']);
            $employeeTypes = EmpTypeMaster::where('Is_Active', 1)->get(['ETy_Id', 'ETy_Code', 'ETy_Name']);

            return response()->json([
                'success' => true,
                'data' => [
                    'departments' => $departments,
                    'designations' => $designations,
                    'payroll_bills' => $payrollBills,
                    'leave_types' => $leaveTypes,
                    'employee_statuses' => $employeeStatuses,
                    'employee_types' => $employeeTypes
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch filter options',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Get filtered employees based on criteria
     * ✅ UPDATED: Added validation for Dpt_Id.*
     */
    public function getFilteredEmployees(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'PRB_id' => 'nullable|exists:payroll_bills,PRB_id',
                'Dpt_Id' => 'nullable|array',
                'Dpt_Id.*' => 'integer|exists:dept_master,Dpt_id',  // ✅ ADDED
                'Dsg_Id' => 'nullable|array',
                'Dsg_Id.*' => 'integer',
                'Est_Id' => 'nullable|exists:emp_status_master,Est_Id',
                'ETy_Id' => 'nullable|exists:emp_type_master,ETy_Id',
                'Emp_Id' => 'nullable|array',
                'Emp_Id.*' => 'integer'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => $validator->errors()
                ], 422);
            }

            $filters = $request->only(['PRB_id', 'Dpt_Id', 'Dsg_Id', 'Est_Id', 'ETy_Id', 'Emp_Id']);
            Log::info('getFilteredEmployees - Filters:', ['filters' => $filters]);

            $employees = LeaveCredit::getFilteredEmployees($filters);
            $totalCount = $employees->count();

            return response()->json([
                'success' => true,
                'data' => [
                    'employees' => $employees->map(function($emp) {
                        $profile = $emp->profile;
                        return [
                            'Emp_Id' => $emp->Emp_Id,
                            'Emp_Code' => $emp->Emp_Code,
                            'First_Name' => $emp->First_Name,
                            'Last_Name' => $emp->Last_Name,
                            'Full_Name' => $emp->First_Name . ' ' . $emp->Last_Name,
                            'Department' => $profile && $profile->department ? $profile->department->Dpt_Name : null,
                            'Designation' => $profile && $profile->designation ? $profile->designation->Dsg_Title : null,
                            'Employee_Status' => $profile && $profile->empStatus ? $profile->empStatus->Est_Name : null,
                            'Employee_Type' => $profile && $profile->empType ? $profile->empType->ETy_Name : null,
                            'Phone' => $emp->Phone,
                            'Email_Id' => $emp->Email_Id
                        ];
                    }),
                    'total' => $totalCount
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch employees',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Display the specified resource.
     */
    public function show($id)
    {
        try {
            $leaveCredit = LeaveCredit::with(['leaveType', 'payrollBill', 'employeeStatus', 'employeeType', 'action'])
                ->findOrFail($id);

            $leaveCredit->departments_list = $leaveCredit->departments_list;
            $leaveCredit->designations_list = $leaveCredit->designations_list;
            $leaveCredit->employees_list = $leaveCredit->employees_list;

            return response()->json([
                'success' => true,
                'data' => $leaveCredit
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Leave credit not found',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 404);
        }
    }

    /**
     * Sanitize filename part (without extension) to remove special characters
     */
    private function sanitizeFileName($fileName)
    {
        $fileName = preg_replace('/[^a-zA-Z0-9\-_]/', '_', $fileName);
        $fileName = preg_replace('/_+/', '_', $fileName);
        $fileName = trim($fileName, '_');
        return $fileName;
    }

    /**
     * Store a newly created resource.
     * ✅ UPDATED: Added validation for Dpt_Id.*, Dsg_Id.*, Emp_Id.*
     */
    public function store(Request $request)
    {
        DB::beginTransaction();

        try {
            $validator = Validator::make($request->all(), [
                'LT_Id' => 'nullable|exists:leave_type_master,LT_id',
                'Fr_Date' => 'required|date',
                'To_Date' => 'required|date|after_or_equal:Fr_Date',
                'Dsg_Id' => 'nullable|array',
                'Dsg_Id.*' => 'exists:designation_master,Dsg_id',  // ✅ ADDED
                'Dpt_Id' => 'nullable|array',
                'Dpt_Id.*' => 'exists:dept_master,Dpt_id',        // ✅ ADDED (IMPORTANT)
                'PRB_id' => 'nullable|exists:payroll_bills,PRB_id',
                'Est_Id' => 'nullable|exists:emp_status_master,Est_Id',
                'ETy_Id' => 'nullable|exists:emp_type_master,ETy_Id',
                'Emp_Id' => 'nullable|array',
                'Emp_Id.*' => 'exists:employee_master,Emp_Id',    // ✅ ADDED
                'Acr_Plcy' => 'required|in:ON DEMAND,YEARLY,HALF_YEARLY,QUARTERLY,MONTHLY',
                'Acr_Days' => 'nullable|integer|min:1|max:31',
                'Act_Id' => 'nullable|exists:action_master,Act_Id',
                'Fnc_Id' => 'nullable|exists:function_types,Fnc_Id'
            ]);

            if ($validator->fails()) {
                Log::error('Validation failed:', [
                    'errors' => $validator->errors()->toArray(),
                    'request_data' => $request->all()
                ]);

                return response()->json([
                    'success' => false,
                    'message' => 'Validation failed',
                    'errors' => $validator->errors()
                ], 422);
            }

            $filters = $request->only(['PRB_id', 'Dpt_Id', 'Dsg_Id', 'Est_Id', 'ETy_Id', 'Emp_Id']);

            Log::info('Store method - Filters being applied:', ['filters' => $filters]);

            $employees = LeaveCredit::getFilteredEmployees($filters);
            $totalEmployees = $employees->count();

            if ($totalEmployees == 0) {
                return response()->json([
                    'success' => false,
                    'message' => 'No employees found matching the criteria'
                ], 422);
            }

            $code = LeaveCredit::generateCode();

            $leaveCredit = LeaveCredit::create([
                'LC_Code' => $code,
                'LT_Id' => $request->LT_Id,
                'Fr_Date' => $request->Fr_Date,
                'To_Date' => $request->To_Date,
                'Dsg_Id' => $request->Dsg_Id,
                'Dpt_Id' => $request->Dpt_Id,
                'PRB_id' => $request->PRB_id,
                'Est_Id' => $request->Est_Id,
                'ETy_Id' => $request->ETy_Id,
                'Emp_Id' => $employees->pluck('Emp_Id')->toArray(),
                'Tot_Emps' => $totalEmployees,
                'Acr_Plcy' => $request->Acr_Plcy,
                'Acr_Days' => $request->Acr_Days,
                'Documents' => [],
                'Act_Id' => $request->Act_Id ?? null
            ]);

            // Handle documents
            $documents = [];
            $fncId = $request->Fnc_Id ?? 1;

            if ($request->hasFile('documents')) {
                $uploadedFiles = $request->file('documents');
                $files = is_array($uploadedFiles) ? $uploadedFiles : [$uploadedFiles];

                foreach ($files as $index => $file) {
                    if (is_null($file) || !$file->isValid()) {
                        continue;
                    }

                    $folderName = 'leave_credits';
                    $folderPath = public_path($folderName);

                    if (!File::exists($folderPath)) {
                        File::makeDirectory($folderPath, 0755, true, true);
                    }

                    $originalName = $file->getClientOriginalName();
                    $originalExtension = $file->getClientOriginalExtension();
                    $nameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);
                    $safeName = $this->sanitizeFileName($nameWithoutExt);

                    $fileName = time() . '_' . $safeName . '.' . $originalExtension;
                    $fullPath = $folderPath . '/' . $fileName;

                    $file->move($folderPath, $fileName);

                    if (file_exists($fullPath)) {
                        $fullUrl = url($folderName . '/' . $fileName);
                        $description = $request->input('documents_description.' . $index, $originalName);

                        $docRecord = DocumentLibrary::create([
                            'Fnc_Id' => $fncId,
                            'Rec_Id' => $leaveCredit->LC_id,
                            'Description' => $description,
                            'Doc_Upload' => $fullUrl,
                            'Serial_No' => count($documents) + 1,
                        ]);

                        $documents[] = [
                            'doc_lib_id' => $docRecord->Doc_Lib,
                            'name' => $description,
                            'description' => $description,
                            'path' => $folderName . '/' . $fileName,
                            'url' => $fullUrl,
                            'type' => $originalExtension,
                            'size' => filesize($fullPath),
                            'original_name' => $originalName,
                            'uploaded_at' => now()->toDateTimeString()
                        ];
                    }
                }
            }

            $leaveCredit->update(['Documents' => $documents]);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Leave credit created successfully',
                'data' => $leaveCredit->fresh(['leaveType', 'payrollBill', 'employeeStatus', 'employeeType'])
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Store failed:', ['error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return response()->json([
                'success' => false,
                'message' => 'Failed to create leave credit',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Update the specified resource.
     * ✅ UPDATED: Added validation for Dpt_Id.*
     */
    public function update(Request $request, $id)
    {
        DB::beginTransaction();

        try {
            $leaveCredit = LeaveCredit::findOrFail($id);

            $rules = [
                'LT_Id'    => 'nullable|exists:leave_type_master,LT_id',
                'Fr_Date'  => 'nullable|date',
                'To_Date'  => 'nullable|date|after_or_equal:Fr_Date',
                'Dsg_Id'   => 'nullable|array',
                'Dsg_Id.*' => 'exists:designation_master,Dsg_id',  // ✅ ADDED
                'Dpt_Id'   => 'nullable|array',
                'Dpt_Id.*' => 'exists:dept_master,Dpt_id',        // ✅ ADDED
                'PRB_id'   => 'nullable|exists:payroll_bills,PRB_id',
                'Est_Id'   => 'nullable|exists:emp_status_master,Est_Id',
                'ETy_Id'   => 'nullable|exists:emp_type_master,ETy_Id',
                'Emp_Id'   => 'nullable|array',
                'Emp_Id.*' => 'exists:employee_master,Emp_Id',    // ✅ ADDED
                'Acr_Plcy' => 'nullable|in:ON DEMAND,YEARLY,HALF_YEARLY,QUARTERLY,MONTHLY',
                'Acr_Days' => 'nullable|integer|min:1|max:31',
                'Status'   => 'boolean',
                'Fnc_Id'   => 'nullable|exists:function_types,Fnc_Id',
                'remarks'  => 'nullable|string|max:500',
                'delete_existing_docs' => 'nullable|boolean',
                'replace_documents' => 'nullable|boolean',
                'update_document_at_index' => 'nullable|integer|min:0',
                'update_document' => 'nullable',
                'update_document_description' => 'nullable|string|max:255',
                'documents' => 'nullable|array',
                'documents.*' => 'nullable',
                'documents_description' => 'nullable|array',
                'documents_description.*' => 'nullable|string|max:255',
            ];

            if ($request->has('Fr_Date') || $request->has('To_Date')) {
                if ($request->has('Fr_Date') && !$request->has('To_Date')) {
                    $rules['To_Date'] = 'required|date|after_or_equal:Fr_Date';
                } elseif (!$request->has('Fr_Date') && $request->has('To_Date')) {
                    $rules['Fr_Date'] = 'required|date';
                }
            }

            $validator = Validator::make($request->all(), $rules);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'errors' => $validator->errors(),
                ], 422);
            }

            $existingDocs = $leaveCredit->Documents ?? [];
            if (is_string($existingDocs)) {
                $existingDocs = json_decode($existingDocs, true) ?? [];
            }

            $indexUpdated = false;
            $finalDocs = $existingDocs;

            // Handle index-based document update
            if ($request->has('update_document_at_index') && $request->has('update_document')) {
                $updateIndex = $request->update_document_at_index;

                if (!isset($existingDocs[$updateIndex])) {
                    return response()->json([
                        'success' => false,
                        'message' => "Document at index {$updateIndex} does not exist"
                    ], 404);
                }

                $oldDocument = $existingDocs[$updateIndex];
                $this->deleteDocumentFile($oldDocument);

                $fncId = $request->Fnc_Id ?? 1;
                $newDocument = null;

                if ($request->hasFile('update_document')) {
                    $file = $request->file('update_document');
                    if ($file && $file->isValid()) {
                        $description = $request->input('update_document_description', $oldDocument['description'] ?? 'Updated Document');
                        $newDocument = $this->processUploadedFile(
                            $file,
                            $description,
                            $fncId,
                            $leaveCredit->LC_id,
                            $updateIndex + 1
                        );
                    }
                } elseif (!empty($request->update_document)) {
                    $description = $request->input('update_document_description', 'Updated Document');
                    $newDocument = $this->processBase64Document(
                        $request->update_document,
                        $description,
                        $description,
                        $fncId,
                        $leaveCredit->LC_id,
                        $updateIndex + 1
                    );
                }

                if ($newDocument) {
                    $finalDocs = $existingDocs;
                    $finalDocs[$updateIndex] = $newDocument;
                    $indexUpdated = true;
                } else {
                    return response()->json([
                        'success' => false,
                        'message' => "Failed to process the new document for index {$updateIndex}"
                    ], 500);
                }
            }

            if (!$indexUpdated && ($request->delete_existing_docs == true || $request->replace_documents == true)) {
                foreach ($existingDocs as $doc) {
                    $this->deleteDocumentFile($doc);
                }
                $finalDocs = [];
            }

            $newDocs = [];
            $fncId = $request->Fnc_Id ?? 1;

            if ($request->hasFile('documents') && !$indexUpdated) {
                $uploadedFiles = $request->file('documents');
                $files = is_array($uploadedFiles) ? $uploadedFiles : [$uploadedFiles];

                foreach ($files as $index => $file) {
                    if (is_null($file) || !$file->isValid()) {
                        continue;
                    }

                    $description = $request->input('documents_description.' . $index, $file->getClientOriginalName());

                    $newDoc = $this->processUploadedFile(
                        $file,
                        $description,
                        $fncId,
                        $leaveCredit->LC_id,
                        count($finalDocs) + count($newDocs) + 1
                    );

                    if ($newDoc) {
                        $newDocs[] = $newDoc;
                    }
                }
            } elseif ($request->has('documents') && is_array($request->documents) && !$indexUpdated) {
                foreach ($request->documents as $index => $base64String) {
                    if (empty($base64String)) {
                        continue;
                    }

                    $originalName = $request->input('documents_description.' . $index, 'Document_' . ($index + 1));
                    $description = $request->input('documents_description.' . $index, $originalName);

                    $newDoc = $this->processBase64Document(
                        $base64String,
                        $originalName,
                        $description,
                        $fncId,
                        $leaveCredit->LC_id,
                        count($finalDocs) + count($newDocs) + 1
                    );

                    if ($newDoc) {
                        $newDocs[] = $newDoc;
                    }
                }
            }

            $allDocs = array_merge($finalDocs, $newDocs);

            foreach ($allDocs as $index => &$doc) {
                $doc['serial_no'] = $index + 1;
                if (isset($doc['doc_lib_id'])) {
                    DocumentLibrary::where('Doc_Lib', $doc['doc_lib_id'])
                        ->update(['Serial_No' => $index + 1]);
                }
            }

            $updateData = [];

            if ($request->has('LT_Id')) $updateData['LT_Id'] = $request->LT_Id;
            if ($request->has('Fr_Date')) $updateData['Fr_Date'] = $request->Fr_Date;
            if ($request->has('To_Date')) $updateData['To_Date'] = $request->To_Date;
            if ($request->has('Dsg_Id')) $updateData['Dsg_Id'] = $request->Dsg_Id;
            if ($request->has('Dpt_Id')) $updateData['Dpt_Id'] = $request->Dpt_Id;
            if ($request->has('PRB_id')) $updateData['PRB_id'] = $request->PRB_id;
            if ($request->has('Est_Id')) $updateData['Est_Id'] = $request->Est_Id;
            if ($request->has('ETy_Id')) $updateData['ETy_Id'] = $request->ETy_Id;
            if ($request->has('Acr_Plcy')) $updateData['Acr_Plcy'] = $request->Acr_Plcy;
            if ($request->has('Acr_Days')) $updateData['Acr_Days'] = $request->Acr_Days;
            if ($request->has('Status')) $updateData['Status'] = $request->Status;
            if ($request->has('remarks')) $updateData['remarks'] = $request->remarks;

            $updateData['Documents'] = $allDocs;

            $filters = $request->only(['PRB_id', 'Dpt_Id', 'Dsg_Id', 'Est_Id', 'ETy_Id', 'Emp_Id']);
            $hasFilters = !empty(array_filter($filters));

            if ($hasFilters) {
                if (!empty($filters['Emp_Id']) && is_array($filters['Emp_Id'])) {
                    $filters['PRB_id'] = null;
                    $filters['Dpt_Id'] = null;
                    $filters['Dsg_Id'] = null;
                    $filters['Est_Id'] = null;
                    $filters['ETy_Id'] = null;
                }

                $employees = LeaveCredit::getFilteredEmployees($filters);
                $totalEmployees = $employees->count();

                if ($totalEmployees == 0) {
                    return response()->json([
                        'success' => false,
                        'message' => 'No employees found matching the criteria'
                    ], 422);
                }

                $updateData['Emp_Id'] = $employees->pluck('Emp_Id')->toArray();
                $updateData['Tot_Emps'] = $totalEmployees;
            }

            $leaveCredit->update($updateData);

            DB::commit();

            return response()->json([
                'success' => true,
                'message' => 'Leave credit updated successfully',
                'data' => $leaveCredit->fresh(['leaveType', 'payrollBill', 'employeeStatus', 'employeeType'])
            ]);

        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('Update failed:', ['error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage(), 'trace' => $e->getTraceAsString()]);
            return response()->json([
                'success' => false,
                'message' => 'Failed to update leave credit',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Detect file extension from decoded data
     */
    private function detectFileExtension($data)
    {
        if (strncmp($data, '%PDF-', 5) === 0) {
            return 'pdf';
        }
        if (strncmp($data, "\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1", 8) === 0) {
            return 'doc';
        }
        if (strncmp($data, "\x50\x4B\x03\x04", 4) === 0) {
            return 'docx';
        }
        if (strncmp($data, "\xFF\xD8\xFF", 3) === 0) {
            return 'jpg';
        }
        if (strncmp($data, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8) === 0) {
            return 'png';
        }
        if (strncmp($data, "GIF89a", 6) === 0 || strncmp($data, "GIF87a", 6) === 0) {
            return 'gif';
        }
        return 'bin';
    }

    /**
     * Get extension from MIME type
     */
    private function getExtensionFromMime($mimeType)
    {
        $mimeMap = [
            'application/pdf' => 'pdf',
            'application/msword' => 'doc',
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',
            'application/vnd.ms-excel' => 'xls',
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',
            'image/jpeg' => 'jpg',
            'image/png' => 'png',
            'image/gif' => 'gif',
        ];

        return $mimeMap[$mimeType] ?? 'bin';
    }

    /**
     * Process uploaded file
     */
    private function processUploadedFile($file, $description, $fncId, $recId, $serialNo)
    {
        try {
            $folderName = 'leave_credits';
            $folderPath = public_path($folderName);

            if (!File::exists($folderPath)) {
                File::makeDirectory($folderPath, 0755, true, true);
            }

            $originalName = $file->getClientOriginalName();
            $originalExtension = $file->getClientOriginalExtension();
            $nameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);
            $safeName = $this->sanitizeFileName($nameWithoutExt);

            $fileName = time() . '_' . $safeName . '.' . $originalExtension;
            $fullPath = $folderPath . '/' . $fileName;

            $file->move($folderPath, $fileName);

            if (file_exists($fullPath)) {
                $fullUrl = url($folderName . '/' . $fileName);

                $docRecord = DocumentLibrary::create([
                    'Fnc_Id' => $fncId,
                    'Rec_Id' => $recId,
                    'Description' => $description,
                    'Doc_Upload' => $fullUrl,
                    'Serial_No' => $serialNo,
                ]);

                return [
                    'doc_lib_id' => $docRecord->Doc_Lib,
                    'name' => $description,
                    'description' => $description,
                    'path' => $folderName . '/' . $fileName,
                    'url' => $fullUrl,
                    'type' => $originalExtension,
                    'size' => filesize($fullPath),
                    'original_name' => $originalName,
                    'uploaded_at' => now()->toDateTimeString()
                ];
            }

            return null;
        } catch (\Exception $e) {
            Log::error('Process uploaded file error: ' . 'Something went wrong. Please try again later.');
            return null;
        }
    }

    /**
     * Process base64 document
     */
    private function processBase64Document($base64String, $originalName, $description, $fncId, $recId, $serialNo)
    {
        try {
            if (preg_match('/^data:([^;]+);base64,(.+)$/', $base64String, $matches)) {
                $mimeType = $matches[1];
                $base64Data = $matches[2];
                $fileData = base64_decode($base64Data);

                if ($fileData === false) {
                    return null;
                }

                $extension = $this->getExtensionFromMime($mimeType);
                if ($extension === 'bin') {
                    $extension = $this->detectFileExtension($fileData);
                }

                $folderName = 'leave_credits';
                $folderPath = public_path($folderName);

                if (!File::exists($folderPath)) {
                    File::makeDirectory($folderPath, 0755, true, true);
                }

                $nameWithoutExt = pathinfo($originalName, PATHINFO_FILENAME);
                $safeName = $this->sanitizeFileName($nameWithoutExt);
                $fileName = time() . '_' . $safeName . '.' . $extension;
                $fullPath = $folderPath . '/' . $fileName;

                file_put_contents($fullPath, $fileData);

                if (file_exists($fullPath)) {
                    $fullUrl = url($folderName . '/' . $fileName);

                    $docRecord = DocumentLibrary::create([
                        'Fnc_Id' => $fncId,
                        'Rec_Id' => $recId,
                        'Description' => $description,
                        'Doc_Upload' => $fullUrl,
                        'Serial_No' => $serialNo,
                    ]);

                    return [
                        'doc_lib_id' => $docRecord->Doc_Lib,
                        'name' => $description,
                        'description' => $description,
                        'path' => $folderName . '/' . $fileName,
                        'url' => $fullUrl,
                        'type' => $extension,
                        'size' => filesize($fullPath),
                        'original_name' => $originalName,
                        'uploaded_at' => now()->toDateTimeString()
                    ];
                }
            }

            return null;
        } catch (\Exception $e) {
            Log::error('Process base64 document error: ' . 'Something went wrong. Please try again later.');
            return null;
        }
    }

    /**
     * Helper method to delete document file
     */
    private function deleteDocumentFile($doc)
    {
        try {
            if (isset($doc['path']) && strpos($doc['path'], 'http') !== 0) {
                $fullPath = public_path($doc['path']);
                if (file_exists($fullPath)) {
                    unlink($fullPath);
                    Log::info('Deleted physical file: ' . $fullPath);
                }
            }

            if (isset($doc['doc_lib_id'])) {
                DocumentLibrary::where('Doc_Lib', $doc['doc_lib_id'])->delete();
                Log::info('Deleted document library record: ' . $doc['doc_lib_id']);
            }
        } catch (\Exception $e) {
            Log::error('Error deleting document: ' . 'Something went wrong. Please try again later.');
        }
    }

    /**
     * Remove the specified resource.
     */
    public function destroy($id)
    {
        try {
            $leaveCredit = LeaveCredit::findOrFail($id);

            if ($leaveCredit->Documents && is_array($leaveCredit->Documents)) {
                foreach ($leaveCredit->Documents as $doc) {
                    $this->deleteDocumentFile($doc);
                }
            }

            $leaveCredit->delete();

            return response()->json([
                'success' => true,
                'message' => 'Leave credit deleted successfully'
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete leave credit',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    /**
     * Test filter endpoint - test any combination
     */
    public function testFilter(Request $request)
    {
        try {
            $filters = $request->only(['PRB_id', 'Dpt_Id', 'Dsg_Id', 'Est_Id', 'ETy_Id', 'Emp_Id']);

            Log::info('Test Filter - Filters:', ['filters' => $filters]);

            $employees = LeaveCredit::getFilteredEmployees($filters);

            return response()->json([
                'success' => true,
                'filters_applied' => $filters,
                'total_employees_found' => $employees->count(),
                'employees' => $employees->map(function($emp) {
                    $profile = $emp->profile;
                    return [
                        'Emp_Id' => $emp->Emp_Id,
                        'Emp_Code' => $emp->Emp_Code,
                        'Name' => $emp->First_Name . ' ' . $emp->Last_Name,
                        'PBillNo' => $profile ? $profile->PBillNo : null,
                        'Dpt_Id' => $profile ? $profile->Dpt_Id : null,
                        'Dsg_Id' => $profile ? $profile->Dsg_Id : null,
                        'Est_Id' => $profile ? $profile->Est_Id : null,
                        'ETy_Id' => $profile ? $profile->ETy_Id : null,
                        'Department' => $profile && $profile->department ? $profile->department->Dpt_Name : null,
                        'Designation' => $profile && $profile->designation ? $profile->designation->Dsg_Title : null,
                        'Employee_Status' => $profile && $profile->empStatus ? $profile->empStatus->Est_Name : null,
                        'Employee_Type' => $profile && $profile->empType ? $profile->empType->ETy_Name : null
                    ];
                })
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ], 500);
        }
    }
}
