<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\LeaveTrans;
use App\Models\FyearMaster;
use Illuminate\Support\Facades\Validator;

class LeaveTransController extends Controller
{
    // ✅ LIST with Pagination + Search
    public function index(Request $request)
    {
        try {

            $perPage = $request->get('per_page', 10);
            $search  = $request->get('search');

            $query = LeaveTrans::with([
                'leaveType',
                'employee',
                'financialYear',
                'statusAction'
            ]);

            // 🔍 Search
            if (!empty($search)) {
                $query->where(function ($q) use ($search) {
                    $q->where('Tr_Type', 'like', "%$search%")
                      ->orWhere('Tr_Mode', 'like', "%$search%")
                      ->orWhere('Tr_Days', 'like', "%$search%")
                      ->orWhere('Paid', 'like', "%$search%")
                      ->orWhere('UnPaid', 'like', "%$search%")
                      ->orWhereHas('employee', function ($q2) use ($search) {
                          $q2->where('Emp_Name', 'like', "%$search%");
                      })
                      ->orWhereHas('leaveType', function ($q3) use ($search) {
                          $q3->where('LT_Name', 'like', "%$search%");
                      });
                });
            }
            $data = $query->orderBy('LTr_id', 'desc')->paginate($perPage);

            return response()->json([
                'success' => true,
                'message' => 'Leave Transactions List',
                'data' => $data
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }

    public function all(Request $request)
    {
        try {

            $search = $request->get('search');

            $query = LeaveTrans::with([
                'leaveType',
                'employee',
                'financialYear',
                'statusAction'
            ]);

            // 🔍 Search
            if (!empty($search)) {
                $query->where(function ($q) use ($search) {
                    $q->where('Tr_Type', 'like', "%$search%")
                      ->orWhere('Tr_Mode', 'like', "%$search%")
                      ->orWhere('Tr_Days', 'like', "%$search%")
                      ->orWhere('Paid', 'like', "%$search%")
                      ->orWhere('UnPaid', 'like', "%$search%")
                      ->orWhereHas('employee', function ($q2) use ($search) {
                          $q2->where('Emp_Name', 'like', "%$search%");
                      })
                      ->orWhereHas('leaveType', function ($q3) use ($search) {
                          $q3->where('LT_Name', 'like', "%$search%");
                      });
                });
            }

            $data = $query->orderBy('LTr_id', 'desc')->get();

            return response()->json([
                'success' => true,
                'message' => 'All Leave Transactions',
                'total'   => $data->count(),
                'data'    => $data
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }

    // ✅ STORE
    public function store(Request $request)
    {
        try {

            $validated = $request->validate([
                'LT_id'   => 'nullable|exists:leave_type_master,LT_id',
                'Emp_Id'  => 'nullable|exists:employee_master,Emp_Id',
                'FY_Id'   => 'nullable|exists:fyear_master,FY_Id',
                'Status'  => 'nullable|exists:action_master,Act_Id',
                'Tr_Type' => 'required|in:ACCRUAL,OPENING_CREDIT,CARRY_FORWARD,DEBIT_APPLIED,CREDIT_CANCELLED,ENCASHMENT,LAPSE,MANUAL_ADJUSTMENT',
                'Tr_Days' => 'nullable|numeric|min:0',
                'Paid'    => 'nullable|numeric|min:0',
                'UnPaid'  => 'nullable|numeric|min:0',
                'Tr_Mode' => 'nullable|in:C,D',
                'LT_Date' => 'nullable|date',
                'Tr_Date' => 'nullable|date',
            ]);

            // If Paid and UnPaid are not provided, set them as null
            $data = LeaveTrans::create($validated);

            return response()->json([
                'success' => true,
                'message' => 'Leave Transaction Created',
                'data' => $data
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }

    // ✅ SHOW
    public function show($id)
    {
        try {

            $data = LeaveTrans::with([
                'leaveType',
                'employee',
                'financialYear',
            ])->find($id);

            if (!$data) {
                return response()->json([
                    'success' => false,
                    'message' => 'Record not found'
                ]);
            }

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }

    // ✅ UPDATE
    public function update(Request $request, $id)
    {
        try {

            $data = LeaveTrans::find($id);

            if (!$data) {
                return response()->json([
                    'success' => false,
                    'message' => 'Record not found'
                ]);
            }

            $validated = $request->validate([
                'LT_id'   => 'sometimes|nullable|exists:leave_type_master,LT_id',
                'Emp_Id'  => 'sometimes|nullable|exists:employee_master,Emp_Id',
                'FY_Id'   => 'sometimes|nullable|exists:fyear_master,FY_Id',
                'Status'  => 'sometimes|nullable|exists:action_master,Act_Id',
                'Tr_Type' => 'sometimes|nullable|in:ACCRUAL,OPENING_CREDIT,CARRY_FORWARD,DEBIT_APPLIED,CREDIT_CANCELLED,ENCASHMENT,LAPSE,MANUAL_ADJUSTMENT',
                'Tr_Days' => 'sometimes|nullable|numeric|min:0',
                'Paid'    => 'sometimes|nullable|numeric|min:0',
                'UnPaid'  => 'sometimes|nullable|numeric|min:0',
                'Tr_Mode' => 'sometimes|nullable|in:C,D',
                'LT_Date' => 'sometimes|nullable|date',
                'Tr_Date' => 'sometimes|nullable|date',
            ]);

            $data->update($validated);

            return response()->json([
                'success' => true,
                'message' => 'Leave Transaction Updated',
                'data' => $data
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }

    // ✅ DELETE (Soft Delete)
    public function destroy($id)
    {
        try {

            $data = LeaveTrans::find($id);

            if (!$data) {
                return response()->json([
                    'success' => false,
                    'message' => 'Record not found'
                ]);
            }

            $data->delete();

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

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }

    public function employeeLeaveSummary(Request $request)
    {
        try {
            $empId = $request->get('emp_id');
            $fyId = $request->get('fy_id'); // Optional: filter by financial year
            $ltId = $request->get('lt_id'); // Optional: filter by leave type

            if (empty($empId)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Employee ID is required'
                ]);
            }

            $query = LeaveTrans::with(['leaveType', 'financialYear'])
                ->where('Emp_Id', $empId);

            // Filter by financial year if provided
            if (!empty($fyId)) {
                $query->where('FY_Id', $fyId);
            }

            // Filter by leave type if provided
            if (!empty($ltId)) {
                $query->where('LT_id', $ltId);
            }

            // Get all transactions
            $transactions = $query->get();

            // Calculate summaries
            $creditedDays = 0;
            $debitedDays = 0;
            $netBalance = 0;
            $totalPaid = 0;
            $totalUnPaid = 0;

            // Transaction type wise breakdown
            $breakdown = [
                'ACCRUAL' => ['credited' => 0, 'debited' => 0],
                'OPENING_CREDIT' => ['credited' => 0, 'debited' => 0],
                'CARRY_FORWARD' => ['credited' => 0, 'debited' => 0],
                'DEBIT_APPLIED' => ['credited' => 0, 'debited' => 0],
                'CREDIT_CANCELLED' => ['credited' => 0, 'debited' => 0],
                'ENCASHMENT' => ['credited' => 0, 'debited' => 0],
                'LAPSE' => ['credited' => 0, 'debited' => 0],
                'MANUAL_ADJUSTMENT' => ['credited' => 0, 'debited' => 0],
            ];

            // Leave type wise summary
            $leaveTypeSummary = [];

            // Financial year wise summary
            $financialYearSummary = [];

            foreach ($transactions as $transaction) {
                $days = floatval($transaction->Tr_Days);
                $mode = $transaction->Tr_Mode;
                $type = $transaction->Tr_Type;
                $paid = $transaction->Paid ? floatval($transaction->Paid) : 0;
                $unpaid = $transaction->UnPaid ? floatval($transaction->UnPaid) : 0;

                // Get leave type details
                $leaveTypeId = $transaction->LT_id;
                $leaveTypeName = $transaction->leaveType ? $transaction->leaveType->LT_Name : 'Unknown';

                // Get financial year details
                $fyIdCurrent = $transaction->FY_Id;
                $fyName = $transaction->financialYear ? $transaction->financialYear->FY_Name : 'Unknown';

                if ($mode === 'C') { // Credit
                    $creditedDays += $days;
                    if (isset($breakdown[$type])) {
                        $breakdown[$type]['credited'] += $days;
                    }
                } elseif ($mode === 'D') { // Debit
                    $debitedDays += $days;
                    $totalPaid += $paid;
                    $totalUnPaid += $unpaid;
                    if (isset($breakdown[$type])) {
                        $breakdown[$type]['debited'] += $days;
                    }
                }

                // Build leave type summary
                if (!isset($leaveTypeSummary[$leaveTypeId])) {
                    $leaveTypeSummary[$leaveTypeId] = [
                        'leave_type_id' => $leaveTypeId,
                        'leave_type_name' => $leaveTypeName,
                        'credited_days' => 0,
                        'debited_days' => 0,
                        'net_balance' => 0,
                        'paid_days' => 0,
                        'unpaid_days' => 0,
                    ];
                }

                if ($mode === 'C') {
                    $leaveTypeSummary[$leaveTypeId]['credited_days'] += $days;
                } else {
                    $leaveTypeSummary[$leaveTypeId]['debited_days'] += $days;
                    $leaveTypeSummary[$leaveTypeId]['paid_days'] += $paid;
                    $leaveTypeSummary[$leaveTypeId]['unpaid_days'] += $unpaid;
                }
                $leaveTypeSummary[$leaveTypeId]['net_balance'] =
                    $leaveTypeSummary[$leaveTypeId]['credited_days'] -
                    $leaveTypeSummary[$leaveTypeId]['debited_days'];

                // Build financial year summary
                if (!isset($financialYearSummary[$fyIdCurrent])) {
                    $financialYearSummary[$fyIdCurrent] = [
                        'financial_year_id' => $fyIdCurrent,
                        'financial_year_name' => $fyName,
                        'credited_days' => 0,
                        'debited_days' => 0,
                        'net_balance' => 0,
                        'paid_days' => 0,
                        'unpaid_days' => 0,
                    ];
                }

                if ($mode === 'C') {
                    $financialYearSummary[$fyIdCurrent]['credited_days'] += $days;
                } else {
                    $financialYearSummary[$fyIdCurrent]['debited_days'] += $days;
                    $financialYearSummary[$fyIdCurrent]['paid_days'] += $paid;
                    $financialYearSummary[$fyIdCurrent]['unpaid_days'] += $unpaid;
                }
                $financialYearSummary[$fyIdCurrent]['net_balance'] =
                    $financialYearSummary[$fyIdCurrent]['credited_days'] -
                    $financialYearSummary[$fyIdCurrent]['debited_days'];
            }

            $netBalance = $creditedDays - $debitedDays;

            // Get employee details
            $employee = \App\Models\EmployeeMaster::find($empId);

            // Get financial year details if provided
            $financialYear = null;
            if (!empty($fyId)) {
                $financialYear = \App\Models\FyearMaster::find($fyId);
            }

            // Get leave type details if provided
            $leaveType = null;
            if (!empty($ltId)) {
                $leaveType = \App\Models\LeaveTypeMaster::find($ltId);
            }

            return response()->json([
                'success' => true,
                'message' => 'Employee leave summary retrieved successfully',
                'data' => [
                    'employee' => [
                        'id' => $empId,
                        'name' => $employee ? $employee->Emp_Name : null,
                        'code' => $employee ? $employee->Emp_Code : null,
                    ],
                    'filters' => [
                        'financial_year' => $financialYear ? [
                            'id' => $financialYear->FY_Id,
                            'name' => $financialYear->FY_Name,
                            'start_date' => $financialYear->FY_StartDate,
                            'end_date' => $financialYear->FY_EndDate,
                        ] : null,
                        'leave_type' => $leaveType ? [
                            'id' => $leaveType->LT_id,
                            'name' => $leaveType->LT_Name,
                            'code' => $leaveType->LT_Code ?? null,
                        ] : null,
                    ],
                    'overall_summary' => [
                        'total_credited_days' => round($creditedDays, 2),
                        'total_debited_days' => round($debitedDays, 2),
                        'net_balance' => round($netBalance, 2),
                        'total_paid_days' => round($totalPaid, 2),
                        'total_unpaid_days' => round($totalUnPaid, 2),
                        'total_transactions' => $transactions->count(),
                    ],
                    'transaction_type_breakdown' => $breakdown,
                    'leave_type_wise_summary' => array_values($leaveTypeSummary),
                    'financial_year_wise_summary' => array_values($financialYearSummary),
                ]
            ]);

        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.'
            ]);
        }
    }



    public function Bulkstore(Request $request)
{
    try {

        $data = $request->all();

        // Validate each item in array
        $validated = Validator::make($data, [
            '*.LT_id'   => 'nullable|exists:leave_type_master,LT_id',
            '*.Emp_Id'  => 'nullable|exists:employee_master,Emp_Id',
            '*.FY_Id'   => 'nullable|exists:fyear_master,FY_Id',
            '*.Tr_Type' => 'required|in:ACCRUAL,OPENING_CREDIT,CARRY_FORWARD,DEBIT_APPLIED,CREDIT_CANCELLED,ENCASHMENT,LAPSE,MANUAL_ADJUSTMENT',
            '*.Tr_Days' => 'nullable|numeric|min:0',
            '*.Paid'    => 'nullable|numeric|min:0',
            '*.UnPaid'  => 'nullable|numeric|min:0',
            '*.Tr_Mode' => 'nullable|in:C,D',
            '*.LT_Date' => 'nullable|date',
            '*.Tr_Date' => 'nullable|date',
        ]);

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

        $insertData = [];

        foreach ($data as $item) {
            $insertData[] = $item;
        }

        LeaveTrans::insert($insertData); // bulk insert

        return response()->json([
            'success' => true,
            'message' => 'Leave Transactions Created Successfully'
        ]);

    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'message' => 'Something went wrong. Please try again later.'
        ]);
    }
}
}
