<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Models\ChlVoucher;
use App\Models\ActivityLog;
use App\Models\PayDetail;
use Illuminate\Http\JsonResponse;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class ChlVoucherController extends Controller
{

    public function index(Request $request): JsonResponse
    {
        try {

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

            $query = ChlVoucher::query();

            $isIncome = $request->get('Is_income');

            if ($request->filled('Is_income')) {
                $query->where('Is_income', $isIncome);
            }

            if (!empty($search)) {
                $query->where(function ($q) use ($search) {
                    $q->where('CV_No', 'like', "%$search%")
                        ->orWhere('SL_Nm', 'like', "%$search%")
                        ->orWhere('Status', 'like', "%$search%");
                });
            }

            $voucherNumbers = $query->select('CV_No')
                ->groupBy('CV_No')
                ->orderBy('CV_No', 'desc')
                ->paginate($perPage);

            $rowsQuery = ChlVoucher::with([
                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod'
            ])
                ->whereIn('CV_No', $voucherNumbers->pluck('CV_No'));


            if ($request->filled('Is_income')) {
                $rowsQuery->where('Is_income', $isIncome);
            }

            $rows = $rowsQuery->get()->groupBy('CV_No');

            $data = $rows->map(function ($items) {

                $header = $items->first();

                return [

                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "Is_income" => $header->Is_income,
                    "Status" => $header->Status ?? 'draft',
                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,
                    "Status_Remark" => $header->Status_Remark,
                    "CV_Ty" => $header->CV_Ty,
                    "Dpt_Id" => $header->Dpt_Id,
                    "Bh_Id" => $header->Bh_Id,
                    "Lg_Id" => $header->Lg_Id,
                    "Ch_Date" => $header->Ch_Date,
                    "formatted_ch_date" => $header->Ch_Date
                        ? Carbon::parse($header->Ch_Date)->format('d-m-Y')
                        : null,
                    "Ch_Start_Date" => $header->Ch_Start_Date,
                    "formatted_date" => Carbon::parse($header->Ch_Start_Date)->format('d-m-Y'),
                    "Ch_End_Date" => $header->Ch_End_Date,
                    "formatted_end_date" => $header->Ch_End_Date
                        ? Carbon::parse($header->Ch_End_Date)->format('d-m-Y')
                        : null,
                    "department" => $header->department,
                    "budget_head" => $header->budgetHead,
                    "ledger" => $header->ledger,
                    "challan_type" => $header->challanType,
                    "HOD_User" => $header->hod,

                    "details" => $items->map(function ($row) {

                        return [

                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,
                            "SL_Id" => $row->SL_Id,
                            "SL_Name" => $row->SL_Nm,
                            "Payment_Mode" => $row->Py_Mode,
                            "Amount" => $row->Amount,
                            "FileNo" => $row->FileNo,
                            "Remarks" => $row->Remarks,
                            "sub_ledger" => $row->subLedger,

                        ];
                    })->values()

                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "Voucher list fetched successfully",
                "data" => $data,
                "pagination" => [
                    "current_page" => $voucherNumbers->currentPage(),
                    "per_page" => $voucherNumbers->perPage(),
                    "total" => $voucherNumbers->total(),
                    "last_page" => $voucherNumbers->lastPage()
                ]
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Something went wrong",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function store(Request $request): JsonResponse
    {
        try {

            $request->validate([
                'CV_Ty' => 'nullable|exists:challan_type,Cht_Id',
                'Ch_Date' => 'nullable|date',
                'Ch_Start_Date' => 'required|date',
                'Ch_End_Date'   => 'nullable|date',
                'CV_No' => 'required|string|max:255',
                'Is_income' => 'nullable|in:Y,N',
                'Dpt_Id' => 'nullable|exists:dept_master,Dpt_id',
                'Bh_Id' => 'nullable|exists:budget_head,Bh_Id',
                'Lg_Id' => 'nullable|exists:ledger_master,Lg_Id',
                'Challan_Detail' => 'required|array|min:1'
            ]);

            // 🔥 Get userId from frontend or auth
            $userId = $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $insertData = [];
            $firstId = null;

            foreach ($request->Challan_Detail as $detail) {

                $voucher = ChlVoucher::create([

                    "CV_Ty" => $request->CV_Ty,
                    "Ch_Date" => $request->Ch_Date ?? null,
                    "Ch_Start_Date" => $request->Ch_Start_Date,
                    "Ch_End_Date" => $request->Ch_End_Date ?? null,
                    "CV_No" => $request->CV_No,
                    "Is_income" => $request->Is_income ?? null,
                    "Dpt_Id" => $request->Dpt_Id,
                    "Bh_Id" => $request->Bh_Id,
                    "Lg_Id" => $request->Lg_Id,

                    "CV_Sr" => $detail['CV_Sr'] ?? null,
                    "SL_Id" => $detail['SL_Id'] ?? null,
                    "SL_Nm" => $detail['SL_Nm'] ?? null,
                    "Py_Mode" => $detail['Py_Mode'] ?? null,
                    "Amount" => $detail['Amount'] ?? null,
                    "FileNo" => $detail['FileNo'] ?? null,
                    "Remarks" => $detail['Remarks'] ?? null,
                    "Status" => "draft",
                    "CHl_HOD" => null,
                    "CHL_HDT" => null,
                    "created_at" => now(),
                    "updated_at" => now()
                ]);

                if (!$firstId) {
                    $firstId = $voucher->CV_Id;
                }
            }

            // ✅ ACTIVITY LOG - ADD
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                12,
                $firstId
            );

            return response()->json([
                "success" => true,
                "message" => "Voucher created successfully"
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error creating voucher",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function show($id): JsonResponse
    {
        try {

            $voucher = ChlVoucher::find($id);

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            $rows = ChlVoucher::with([
                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod'

            ])
                ->where('CV_No', $voucher->CV_No)
                ->get()
                ->groupBy('CV_No');

            $data = $rows->map(function ($items) {

                $header = $items->first();

                return [

                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "Is_income" => $header->Is_income,
                    "Status" => $header->Status ?? 'draft',
                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,
                    "Status_Remark" => $header->Status_Remark,
                    "CV_Ty" => $header->CV_Ty,
                    "Dpt_Id" => $header->Dpt_Id,
                    "Bh_Id" => $header->Bh_Id,
                    "Lg_Id" => $header->Lg_Id,
                    "Ch_Date" => $header->Ch_Date,
                    "formatted_ch_date" => $header->Ch_Date
                        ? Carbon::parse($header->Ch_Date)->format('d-m-Y')
                        : null,
                    "Ch_Start_Date" => $header->Ch_Start_Date,
                    "formatted_date" => Carbon::parse($header->Ch_Start_Date)->format('d-m-Y'),
                    "Ch_End_Date" => $header->Ch_End_Date,
                    "formatted_end_date" => $header->Ch_End_Date
                        ? Carbon::parse($header->Ch_End_Date)->format('d-m-Y')
                        : null,
                    "department" => $header->department,
                    "budget_head" => $header->budgetHead,
                    "ledger" => $header->ledger,
                    "challan_type" => $header->challanType,
                    "HOD_User" => $header->hod,
                    "details" => $items->map(function ($row) {

                        return [

                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,

                            "SL_Id" => $row->SL_Id,
                            "SL_Name" => $row->SL_Nm,

                            "Payment_Mode" => $row->Py_Mode,
                            "Amount" => $row->Amount,
                            "FileNo" => $row->FileNo,
                            "Remarks" => $row->Remarks,

                            "sub_ledger" => $row->subLedger

                        ];
                    })

                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "Voucher fetched successfully",
                "data" => $data
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Something went wrong",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function update(Request $request, $id): JsonResponse
    {
        try {

            $request->validate([
                "Ch_Date" => "sometimes|nullable|date",
                "Ch_Start_Date" => "required|date",
                "Ch_End_Date"   => "sometimes|nullable|date",
                "CV_No" => "required|string",
                'Is_income' => 'nullable|in:Y,N',
                "Dpt_Id" => "required|integer",
                "Bh_Id" => "required|integer",
                "Lg_Id" => "required|integer",
                "CV_Ty" => "nullable|integer",
                "Challan_Detail" => "required|array|min:1"
            ]);

            // 🔥 Get userId from frontend or auth
            $userId = $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            if ($voucher->Status !== 'draft') {
                return response()->json([
                    "success" => false,
                    "message" => "Approved/Rejected voucher cannot be edited"
                ]);
            }
            $cvNo = $voucher->CV_No;

            // HARD DELETE OLD DETAILS
            ChlVoucher::where('CV_No', $cvNo)->delete();

            $insertData = [];

            foreach ($request->Challan_Detail as $detail) {

                $insertData[] = [

                    "CV_Ty" => $request->CV_Ty,
                    "Ch_Date" => $request->Ch_Date ?? null,
                    "Ch_Start_Date" => $request->Ch_Start_Date,
                    "Ch_End_Date" => $request->Ch_End_Date ?? null,
                    "CV_No" => $request->CV_No,
                    "Is_income" => $request->Is_income ?? null,
                    "Dpt_Id" => $request->Dpt_Id,
                    "Bh_Id" => $request->Bh_Id,
                    "Lg_Id" => $request->Lg_Id,

                    "CV_Sr" => $detail['CV_Sr'] ?? null,
                    "SL_Id" => $detail['SL_Id'] ?? null,
                    "SL_Nm" => $detail['SL_Nm'] ?? null,
                    "Py_Mode" => $detail['Py_Mode'] ?? null,
                    "Amount" => $detail['Amount'] ?? null,
                    "FileNo" => $detail['FileNo'] ?? null,
                    "Remarks" => $detail['Remarks'] ?? null,

                    "created_at" => now(),
                    "updated_at" => now()

                ];
            }

            ChlVoucher::insert($insertData);

            // ✅ ACTIVITY LOG - EDIT
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                2,
                $id
            );

            return response()->json([
                "success" => true,
                "message" => "Voucher updated successfully"
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error updating voucher",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function destroy($id): JsonResponse
    {
        try {

            // 🔥 Get userId from request or auth
            $userId = request()->UserId ?? auth()->user()->Usr_Id ?? null;

            $voucher = ChlVoucher::find($id);

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            $cvNo = $voucher->CV_No;
            $cvId = $voucher->CV_Id;

            // ✅ ACTIVITY LOG - DELETE (BEFORE ACTUAL DELETE)
            $this->storeActivityLog(
                $userId,
                'CHAL',
                7,
                $cvId
            );

            ChlVoucher::where("CV_No", $cvNo)->delete();

            return response()->json([
                "success" => true,
                "message" => "Voucher deleted successfully"
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error deleting voucher",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }



    public function all(Request $request): JsonResponse
    {
        try {

            $query = ChlVoucher::with([
                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod'
            ]);

            if ($request->filled('Is_income')) {
                $query->where('Is_income', $request->Is_income);
            }

            if ($request->filled('search')) {

                $search = $request->search;

                $query->where(function ($q) use ($search) {

                    $q->where('CV_No', 'like', "%$search%")
                        ->orWhere('SL_Nm', 'like', "%$search%")
                        ->orWhere('Status', 'like', "%$search%");
                });
            }

            $vouchers = $query
                ->orderBy('CV_No', 'desc')
                ->get()
                ->groupBy('CV_No');

            $data = $vouchers->map(function ($items) {

                $header = $items->first();

                return [

                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "Is_income" => $header->Is_income,
                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "Status_Remark" => $header->Status_Remark,
                    "Status" => $header->Status,
                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,

                    "CV_Ty" => $header->CV_Ty,
                    "Dpt_Id" => $header->Dpt_Id,
                    "Bh_Id" => $header->Bh_Id,
                    "Lg_Id" => $header->Lg_Id,
                    "Ch_Date" => $header->Ch_Date,
                    "formatted_ch_date" => $header->Ch_Date
                        ? Carbon::parse($header->Ch_Date)->format('d-m-Y')
                        : null,
                    "Ch_Start_Date" => $header->Ch_Start_Date,
                    "formatted_date" => \Carbon\Carbon::parse($header->Ch_Start_Date)->format('d-m-Y'),
                    "Ch_End_Date" => $header->Ch_End_Date,
                    "formatted_end_date" => $header->Ch_End_Date
                        ? Carbon::parse($header->Ch_End_Date)->format('d-m-Y')
                        : null,
                    "department" => $header->department,
                    "budget_head" => $header->budgetHead,
                    "ledger" => $header->ledger,
                    "challan_type" => $header->challanType,
                    "HOD_User" => $header->hod,

                    "details" => $items->map(function ($row) {

                        return [

                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,
                            "SL_Id" => $row->SL_Id,
                            "SL_Name" => $row->SL_Nm,
                            "Payment_Mode" => $row->Py_Mode,
                            "Amount" => $row->Amount,
                            "FileNo" => $row->FileNo,
                            "Remarks" => $row->Remarks,
                            "sub_ledger" => $row->subLedger

                        ];
                    })->values()

                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "All vouchers fetched successfully",
                "data" => $data
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Something went wrong",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }



    private function formatVoucherData($vouchers)
    {

        return $vouchers->map(function ($rows) {

            $header = $rows->first();

            return [

                "CV_Id" => $header->CV_Id,
                "CV_No" => $header->CV_No,

                "Ch_Start_Date" => $header->Ch_Start_Date,

                "formatted_date" => Carbon::parse($header->Ch_Start_Date)->format("d-m-Y"),

                "department" => $header->department,
                "budget_head" => $header->budgetHead,
                "ledger" => $header->ledger,
                "challan_type" => $header->challanType,

                "details" => $rows->map(function ($row) {

                    return [

                        "CV_Id" => $row->CV_Id,
                        "CV_Sr" => $row->CV_Sr,
                        "SL_Id" => $row->SL_Id,
                        "SL_Name" => $row->SL_Nm,
                        "Payment_Mode" => $row->Py_Mode,
                        "Amount" => $row->Amount,
                        "FileNo" => $row->FileNo,
                        "Remarks" => $row->Remarks,
                        "sub_ledger" => $row->subLedger

                    ];
                })

            ];
        })->values();
    }



    public function updateStatus(Request $request, $id): JsonResponse
    {
        try {

            $request->validate([
                "Status"  => "required|in:hod_app,hod_rej",
                "CHl_HOD" => "required|exists:user_master,Usr_Id",
                "Status_Remark" => "nullable|string"
            ]);

            // 🔥 Get userId from CHl_HOD or frontend or auth
            $userId = $request->CHl_HOD ?? $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $voucher = ChlVoucher::find($id);

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            if ($voucher->Status !== 'draft') {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher already processed"
                ]);
            }

            // update all rows with same voucher number
            ChlVoucher::where("CV_No", $voucher->CV_No)->update([
                "Status"  => $request->Status,
                "CHl_HOD" => $request->CHl_HOD,
                "Status_Remark" => $request->Status_Remark,
                "CHL_HDT" => now()
            ]);

            // ✅ ACTIVITY LOG - STATUS UPDATE
            $statusActionId = ($request->Status == 'hod_app') ? 13 : 14;
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                $statusActionId,
                $id
            );

            // fetch updated voucher
            $rows = ChlVoucher::with([
                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod'
            ])
                ->where('CV_No', $voucher->CV_No)
                ->get()
                ->groupBy('CV_No');

            $data = $rows->map(function ($items) {

                $header = $items->first();

                return [

                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "Status" => $header->Status,
                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,
                    "HOD_User" => $header->hod,
                    "Status_Remark" => $header->Status_Remark,
                    "CV_Ty" => $header->CV_Ty,
                    "Dpt_Id" => $header->Dpt_Id,
                    "Bh_Id" => $header->Bh_Id,
                    "Lg_Id" => $header->Lg_Id,

                    "Ch_Start_Date" => $header->Ch_Start_Date,
                    "formatted_date" => Carbon::parse($header->Ch_Start_Date)->format('d-m-Y'),

                    "department" => $header->department,
                    "budget_head" => $header->budgetHead,
                    "ledger" => $header->ledger,
                    "challan_type" => $header->challanType,

                    "details" => $items->map(function ($row) {

                        return [

                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,

                            "SL_Id" => $row->SL_Id,
                            "SL_Name" => $row->SL_Nm,

                            "Payment_Mode" => $row->Py_Mode,
                            "Amount" => $row->Amount,
                            "FileNo" => $row->FileNo,
                            "Remarks" => $row->Remarks,

                            "sub_ledger" => $row->subLedger

                        ];
                    })->values()

                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "Voucher status updated successfully",
                "data" => $data
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error updating voucher status",
                "error"   => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }



    ///////////////////////////////////////New Function for New Challan//////////////////////////////////////////////



    public function indexNewChallan(Request $request): JsonResponse
    {
        try {
            $perPage = $request->get('per_page', 20);
            $search  = $request->get('search');

            $query = ChlVoucher::query();

            // 🔍 Search
            if (!empty($search)) {
                $query->where(function ($q) use ($search) {
                    $q->where('CV_No', 'like', "%$search%")
                        ->orWhere('SL_Nm', 'like', "%$search%")
                        ->orWhereHas('department', function ($q2) use ($search) {
                            $q2->where('Dpt_Name', 'like', "%$search%");
                        });
                });
            }

            // 🔍 Filters
            if ($request->filled('Is_income')) {
                $query->where('Is_income', $request->Is_income);
            }

            if ($request->filled('Dpt_Id')) {
                $query->where('Dpt_Id', $request->Dpt_Id);
            }

            if ($request->filled('Status')) {
                $query->whereIn('Status', array_unique(explode(',', $request->Status)));
            }

            // ✅ FIXED QUERY (GROUP BY ISSUE SOLVED)
            $voucherNumbers = $query->select('CV_No', DB::raw('MAX(Ch_Date) as latest_date'))
                ->groupBy('CV_No')
                ->orderByDesc('latest_date')
                ->paginate($perPage);

            // 📦 Fetch full records
            $rows = ChlVoucher::with([
                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod',
                'statusMaster',
                'tenderType',
                'RStatus',
                'chequeStatus',
                "payModes",
                "payModes.ledger"
            ])
                ->whereIn('CV_No', $voucherNumbers->pluck('CV_No'))
                ->orderBy('Ch_Date', 'desc')
                ->get()
                ->groupBy('CV_No');

            // 🧠 Format response
            $data = $rows->map(function ($items) {
                $header = $items->first();

                return [
                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "TnT_Id" => $header->TnT_Id,
                    "Is_income" => $header->Is_income,
                    "Status" => $header->Status,
                    "R_Status" => $header->R_Status,
                    "Status_Remark" => $header->Status_Remark,
                    "Acc_Chl_No" => $header->Acc_Chl_No,
                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,
                    "CV_Ty" => $header->CV_Ty,
                    "Dpt_Id" => $header->Dpt_Id,
                    "Bh_Id" => $header->Bh_Id,
                    "Lg_Id" => $header->Lg_Id,
                    "SL_Id" => $header->SL_Id,
                    "PayMd_ID" => $header->PayMd_ID,
                    "SL_Nm" => $header->SL_Nm,
                    "Py_Mode" => $header->Py_Mode,
                    "Is_Cheque_Verf" => $header->Is_Cheque_Verf,
                    "Cheque_Cnl_Remark" => $header->Cheque_Cnl_Remark,
                    "Chq_Status" => $header->Chq_Status,
                    "Amount" => $header->Amount,
                    "Total_Amount" => $header->Total_Amount,
                    "Net_Amount" => $header->Net_Amount,
                    "FileNo" => $header->FileNo,
                    "Remarks" => $header->Remarks,

                    "Ch_Date" => $header->Ch_Date,
                    "formatted_ch_date" => $header->Ch_Date ? Carbon::parse($header->Ch_Date)->format('d-m-Y') : null,

                    "Ch_Start_Date" => $header->Ch_Start_Date,
                    "formatted_start_date" => $header->Ch_Start_Date ? Carbon::parse($header->Ch_Start_Date)->format('d-m-Y') : null,

                    "Ch_End_Date" => $header->Ch_End_Date,
                    "formatted_end_date" => $header->Ch_End_Date ? Carbon::parse($header->Ch_End_Date)->format('d-m-Y') : null,

                    "Acc_Chl_Date" => $header->Acc_Chl_Date,
                    "formatted_Acc_Chl_Date" => $header->Acc_Chl_Date ? Carbon::parse($header->Acc_Chl_Date)->format('d-m-Y') : null,

                    "Chq_Date" => $header->Chq_Date,
                    "Bank_Name" => $header->Bank_Name,
                    "IFSC_Code" => $header->IFSC_Code,
                    "Acc_No" => $header->Acc_No,
                    "Chq_No" => $header->Chq_No,
                    "Rec_Date" => $header->Rec_Date,

                    // Relations
                    "department" => $header->department ? [
                        "Dpt_id" => $header->department->Dpt_id,
                        "Dpt_Name" => $header->department->Dpt_Name,
                        "Dpt_Code" => $header->department->Dpt_Code
                    ] : null,

                    "challan_type" => $header->challanType ? [
                        "Cht_Id" => $header->challanType->Cht_Id,
                        "Cht_Name" => $header->challanType->Cht_Name,
                        "Cht_Code" => $header->challanType->Cht_Code
                    ] : null,

                    "tender_type" => $header->tenderType ? [
                        "Tnt_Id" => $header->tenderType->TnT_ID,
                        "Tnt_Code" => $header->tenderType->TnT_Code,
                        "Tnt_Name" => $header->tenderType->TnT_Name
                    ] : null,

                    "status_master" => $header->statusMaster ? [
                        "Act_Id" => $header->statusMaster->Act_Id,
                        "St_Name" => $header->statusMaster->St_Name
                    ] : null,

                    "details" => $items->map(function ($row) {
                        return [
                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,
                            "Status" => $row->Status,
                            "SL_Nm" => $row->SL_Nm,
                            "Amount" => $row->Amount,

                            "paymode" => [
                                "PayMd_ID" => optional($row->payModes)->PayMd_ID,
                                "PayMd_Name" => optional($row->payModes)->PayMd_Name,
                                "ledger" => [
                                    "Lg_Id" => optional(optional($row->payModes)->ledger)->Lg_Id,
                                    "Lg_Name" => optional(optional($row->payModes)->ledger)->Lg_Name,
                                ]
                            ]
                        ];
                    })->values()
                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "New challan list fetched",
                "data" => $data,
                "pagination" => [
                    "current_page" => $voucherNumbers->currentPage(),
                    "per_page" => $voucherNumbers->perPage(),
                    "total" => $voucherNumbers->total(),
                    "last_page" => $voucherNumbers->lastPage()
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                "success" => false,
                "message" => "Error",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function showNewChallan($id): JsonResponse
    {
        try {
            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            $rows = ChlVoucher::with([
                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod',
                'statusMaster',
                'tenderType',
                'RStatus',
                'chequeStatus',
                "payModes",
                "payModes.ledger"
            ])
                ->where('CV_No', $voucher->CV_No)
                ->get()
                ->groupBy('CV_No');

            if ($rows->isEmpty()) {
                return response()->json([
                    "success" => false,
                    "message" => "No challan data found"
                ], 404);
            }

            $data = $rows->map(function ($items) {

                $header = $items->first();

                return [
                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,
                    "TnT_Id" => $header->TnT_Id,
                    "Is_income" => $header->Is_income,
                    "Is_Cheque_Verf" => $header->Is_Cheque_Verf,
                    "Cheque_Cnl_Remark" => $header->Cheque_Cnl_Remark,
                    "Chq_Status" => $header->Chq_Status,
                    "R_Status" => $header->R_Status,
                    "Status" => $header->Status,
                    "Status_Remark" => $header->Status_Remark,
                    "Acc_Chl_No" => $header->Acc_Chl_No,
                    "Ch_Date" => $header->Ch_Date,
                    "formatted_ch_date" => $header->Ch_Date
                        ? \Carbon\Carbon::parse($header->Ch_Date)->format('d-m-Y')
                        : null,

                    "Acc_Chl_Date" => $header->Acc_Chl_Date,
                    "formatted_Acc_Chl_Date" => $header->Acc_Chl_Date
                        ? \Carbon\Carbon::parse($header->Acc_Chl_Date)->format('d-m-Y')
                        : null,
                    "Total_Amount" => $header->Total_Amount,
                    "Net_Amount" => $header->Net_Amount,
                    "department" => $header->department,
                    "challan_type" => $header->challanType,
                    "tender_type" => $header->tenderType,
                    "status_master" => $header->statusMaster,
                    "RStatus" => $header->RStatus,
                    "cheque_status" => $header->chequeStatus,
                    "HOD_User" => $header->hod,
                    "details" => $items->map(function ($row) {
                        return [
                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,
                            "Lg_Id" => $row->Lg_Id,
                            "Bh_Id" => $row->Bh_Id,
                            "SL_Id" => $row->SL_Id,
                            "PayMd_ID" => $row->PayMd_ID,
                            "SL_Nm" => $row->SL_Nm,
                            "Amount" => $row->Amount,
                            "Payment_Mode" => $row->Py_Mode,
                            "FileNo" => $row->FileNo,
                            "Remarks" => $row->Remarks,
                            "Penalty_Amount" => $row->Penalty_Amount,
                            "GST_No" => $row->GST_No,
                            "Chq_Date" => $row->Chq_Date,
                            "Bank_Name" => $row->Bank_Name,
                            "IFSC_Code" => $row->IFSC_Code,
                            "Acc_No" => $row->Acc_No,
                            "Chq_No" => $row->Chq_No,
                            "Rec_Date" => $row->Rec_Date,
                            "Is_Cheque_Verf" => $row->Is_Cheque_Verf,
                            "Cheque_Cnl_Remark" => $row->Cheque_Cnl_Remark,
                            "Chq_Status" => $row->Chq_Status,
                            "ledger" => [
                                "Lg_Id" => $row->ledger->Lg_Id ?? null,
                                "Lg_Name" => $row->ledger->Lg_Name ?? null
                            ],
                            "budget_head" => [
                                "Bh_Id" => $row->budgetHead->Bh_Id ?? null,
                                "Gr_Nm" => $row->budgetHead->Gr_Nm ?? null
                            ],
                            "sub_ledger" => [
                                "SL_Id" => $row->subLedger->SL_Id ?? null,
                                "SL_Name" => $row->subLedger->SL_Name ?? null
                            ],

                            "paymode" => [
                                "PayMd_ID" => $row->payModes->PayMd_ID ?? null,
                                "PayMd_Name" => $row->payModes->PayMd_Name ?? null,
                                "ledger" => [
                                    "Lg_Id" => $row->payModes->ledger->Lg_Id ?? null,
                                    "Lg_Name" => $row->payModes->ledger->Lg_Name ?? null,

                                ]
                            ]


                        ];
                    })->values()
                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "New challan details fetched successfully",
                "data" => $data
            ]);
        } catch (\Exception $e) {
            return response()->json([
                "success" => false,
                "message" => "Error",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function storeNewChallan(Request $request): JsonResponse
    {
        try {

            $request->validate([
                'Ch_Date' => 'nullable|date',
                'Acc_Chl_Date' => 'nullable|date',
                'CV_No' => 'required|string|max:255',
                'TnT_Id' => 'nullable|exists:tender_type,Tnt_Id',
                // 'CV_No' => 'required|string|max:255',
                'Total_Amount' => 'nullable|numeric',
                'Net_Amount' => 'nullable|numeric',
                'Dpt_Id' => 'nullable|exists:dept_master,Dpt_id',
                'CV_Ty' => 'nullable|exists:challan_type,Cht_Id',
                'Challan_Detail' => 'required|array|min:1'
            ]);

            // 🔥 Get userId from frontend or auth
            $userId = $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $insertData = [];
            $firstId = null;

            foreach ($request->Challan_Detail as $detail) {

                $voucher = ChlVoucher::create([
                    "Ch_Date" => $request->Ch_Date ?? null,
                    "Acc_Chl_Date" => $request->Acc_Chl_Date ?? null,
                    "CV_No" => $request->CV_No ?? null,
                    "TnT_Id" => $request->TnT_Id ?? null,
                    "Total_Amount" => $request->Total_Amount ?? null,
                    "Net_Amount" => $request->Net_Amount ?? null,
                    "Dpt_Id" => $request->Dpt_Id ?? null,
                    "CV_Ty" => $request->CV_Ty ?? null,
                    "Is_income" => $request->Is_income ?? null,
                    "Is_Cheque_Verf" => $request->Is_Cheque_Verf ?? 'N',
                    "Cheque_Cnl_Remark" => $request->Cheque_Cnl_Remark ?? null,
                    "CV_Sr" => $detail['CV_Sr'] ?? null,
                    "Lg_Id" => $detail['Lg_Id'] ?? null,
                    "Bh_Id" => $detail['Bh_Id'] ?? null,
                    "PayMd_ID" => $detail['PayMd_ID'] ?? null,
                    "SL_Nm" => $detail['SL_Nm'] ?? null,
                    "Amount" => $detail['Amount'] ?? null,
                    "Py_Mode" => $detail['Py_Mode'] ?? null,
                    "FileNo" => $detail['FileNo'] ?? null,
                    "Remarks" => $detail['Remarks'] ?? null,
                    "GST_No" => $detail['GST_No'] ?? null,
                    "Penalty_Amount" => $detail['Penalty_Amount'] ?? null,
                    "Chq_Date" => $detail['Chq_Date'] ?? null,
                    "Bank_Name" => $detail['Bank_Name'] ?? null,
                    "IFSC_Code" => $detail['IFSC_Code'] ?? null,
                    "Acc_No" => $detail['Acc_No'] ?? null,
                    "Chq_No" => $detail['Chq_No'] ?? null,
                    "Rec_Date" => $detail['Rec_Date'] ?? null,
                    "Chq_Status" => $request->Chq_Status ?? null,
                    "Status" =>  $request->Status ?? null,
                    "CHl_HOD" => null,
                    "CHL_HDT" => null,
                    "created_at" => now(),
                    "updated_at" => now()
                ]);

                if (!$firstId) {
                    $firstId = $voucher->CV_Id;
                }
            }

            // ✅ ACTIVITY LOG - ADD NEW CHALLAN
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                12,
                $firstId
            );

            return response()->json([
                "success" => true,
                "message" => "Voucher created successfully"
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error creating voucher",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }





    public function updateNewChallan(Request $request, $id): JsonResponse
    {
        try {

            $request->validate([
                "Ch_Date" => "sometimes|nullable|date",
                "Acc_Chl_Date" => "sometimes|nullable|date",
                "CV_No" => "nullable|string",
                "TnT_Id" => "nullable|exists:tender_type,Tnt_Id",
                "Total_Amount" => "nullable|numeric",
                "Net_Amount" => "nullable|numeric",
                "Dpt_Id" => "nullable|exists:dept_master,Dpt_id",
                "CV_Ty" => "nullable|exists:challan_type,Cht_Id",
                "Challan_Detail" => "nullable|array|min:1"
            ]);

            // 🔥 Get userId from frontend or auth
            $userId = $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            $cvNo = $voucher->CV_No;
            $oldRows = ChlVoucher::where('CV_No', $cvNo)->get();

            ChlVoucher::where('CV_No', $cvNo)->delete();

            $details = $request->Challan_Detail ?? [];
            $insertData = [];

            foreach ($oldRows as $index => $old) {
                $detail = $details[$index] ?? [];

                $insertData[] = [
                    "Ch_Date" => $request->Ch_Date ?? $old->Ch_Date,
                    "Acc_Chl_Date" => $request->Acc_Chl_Date ?? $old->Acc_Chl_Date,
                    "CV_No" => $request->CV_No ?? $old->CV_No,
                    "TnT_Id" => $request->TnT_Id ?? $old->TnT_Id,
                    "Total_Amount" => $request->Total_Amount ?? $old->Total_Amount,
                    "Net_Amount" => $request->Net_Amount ?? $old->Net_Amount,
                    "Dpt_Id" => $request->Dpt_Id ?? $old->Dpt_Id,
                    "CV_Ty" => $request->CV_Ty ?? $old->CV_Ty,
                    "Acc_Chl_No" => $request->Acc_Chl_No ?? $old->Acc_Chl_No,
                    "Is_income" => $request->Is_income ?? $old->Is_income,
                    "Is_Cheque_Verf" => $request->Is_Cheque_Verf ?? $old->Is_Cheque_Verf,
                    "Cheque_Cnl_Remark" => $request->Cheque_Cnl_Remark ?? $old->Cheque_Cnl_Remark,
                    "Chq_Status" => $request->Chq_Status ?? $old->Chq_Status,
                    "CV_Sr" => $detail['CV_Sr'] ?? $old->CV_Sr,
                    "Lg_Id" => $detail['Lg_Id'] ?? $old->Lg_Id,
                    "Bh_Id" => $detail['Bh_Id'] ?? $old->Bh_Id,
                    "PayMd_ID" => $detail['PayMd_ID'] ?? null,
                    "SL_Nm" => $detail['SL_Nm'] ?? $old->SL_Nm,
                    "Amount" => $detail['Amount'] ?? $old->Amount,
                    "Py_Mode" => $detail['Py_Mode'] ?? $old->Py_Mode,
                    "FileNo" => $detail['FileNo'] ?? $old->FileNo,
                    "Remarks" => $detail['Remarks'] ?? $old->Remarks,
                    "GST_No" => $detail['GST_No'] ?? $old->GST_No,
                    "Penalty_Amount" => $detail['Penalty_Amount'] ?? $old->Penalty_Amount,
                    "Chq_Date" => $detail['Chq_Date'] ?? $old->Chq_Date,
                    "Bank_Name" => $detail['Bank_Name'] ?? $old->Bank_Name,
                    "IFSC_Code" => $detail['IFSC_Code'] ?? $old->IFSC_Code,
                    "Acc_No" => $detail['Acc_No'] ?? $old->Acc_No,
                    "Chq_No" => $detail['Chq_No'] ?? $old->Chq_No,
                    "Rec_Date" => $detail['Rec_Date'] ?? $old->Rec_Date,
                    "Status" => $request->Status ?? $old->Status,
                    "CHl_HOD" => $old->CHl_HOD,
                    "CHL_HDT" => $old->CHL_HDT,
                    "created_at" => $old->created_at,
                    "updated_at" => now()
                ];
            }

            ChlVoucher::insert($insertData);

            // ✅ ACTIVITY LOG - EDIT
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                2,
                $id
            );

            return response()->json([
                "success" => true,
                "message" => "Voucher updated successfully"
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error updating voucher",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function updateVoucherStatus(Request $request, $id): JsonResponse
    {
        try {

            $request->validate([
                'Status' => 'required|exists:action_master,Act_Id',
                'R_Status' => 'nullable|exists:action_master,Act_Id',
                'Chq_Status' => 'nullable|exists:action_master,Act_Id',
                'Status_Remark' => 'nullable|string|max:500',
                'Acc_Chl_No' => 'nullable|string|max:255',
                'CHl_HOD' => 'nullable|exists:user_master,Usr_Id',
                'Last_Approval_Date' => 'nullable|date'
            ]);

            // 🔥 Get userId from CHl_HOD or frontend or auth
            $userId = $request->CHl_HOD ?? $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            $cvNo = $voucher->CV_No;


            $updateData = [
                "Status" => $request->Status,
                "R_Status" => $request->R_Status,
                "Chq_Status" => $request->Chq_Status,
                "Status_Remark" => $request->Status_Remark,
                "CHL_HDT" => now()
            ];
            if ($request->filled('Last_Approval_Date')) {
                $updateData['Last_Approval_Date'] = $request->Last_Approval_Date;
            }

            // if ($request->has('Acc_Chl_No') && $request->Acc_Chl_No !== null) {
            //     $allRecords = ChlVoucher::whereNotNull('Acc_Chl_No')->pluck('Acc_Chl_No');
            //     $numericValues = $allRecords->filter(function ($value) {
            //         return is_numeric($value);
            //     })->map(function ($value) {
            //         return (int)$value;
            //     });
            //     $maxAccChlNo = $numericValues->max() ?? 0;
            //     $newReceiptNo = $maxAccChlNo + 1;
            //     $updateData["Acc_Chl_No"] = $newReceiptNo;
            // }

            if ($request->has('Acc_Chl_No') && $request->Acc_Chl_No !== null) {
                // Get the Is_income value from the voucher
                $isIncome = $voucher->Is_income;

                // Query to get max Acc_Chl_No based on income/expense type
                $query = ChlVoucher::whereNotNull('Acc_Chl_No')
                    ->where('Is_income', $isIncome);

                $allRecords = $query->pluck('Acc_Chl_No');
                $numericValues = $allRecords->filter(function ($value) {
                    return is_numeric($value);
                })->map(function ($value) {
                    return (int)$value;
                });

                $maxAccChlNo = $numericValues->max() ?? 0;
                $newReceiptNo = $maxAccChlNo + 1;
                $updateData["Acc_Chl_No"] = $newReceiptNo;
                $updateData["Acc_Chl_Date"] = now()->toDateString();
            }

            if ($request->has('CHl_HOD') && $request->CHl_HOD) {
                $updateData["CHl_HOD"] = $request->CHl_HOD;
            }

            ChlVoucher::where("CV_No", $cvNo)->update($updateData);

            // ✅ ACTIVITY LOG - STATUS CHANGE
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                $request->Status,
                $id
            );

            // $nextReceiptNumber = null;
            // if (isset($updateData["Acc_Chl_No"])) {
            //     $allRecords = ChlVoucher::whereNotNull('Acc_Chl_No')->pluck('Acc_Chl_No');
            //     $numericValues = $allRecords->filter(function ($value) {
            //         return is_numeric($value);
            //     })->map(function ($value) {
            //         return (int)$value;
            //     });
            //     $currentMax = $numericValues->max() ?? 0;
            //     $nextReceiptNumber = $currentMax + 1;
            // }

            $nextReceiptNumber = null;
            if (isset($updateData["Acc_Chl_No"])) {
                // Get next receipt number for the same type
                $isIncome = $voucher->Is_income;
                $query = ChlVoucher::whereNotNull('Acc_Chl_No')
                    ->where('Is_income', $isIncome);
                $allRecords = $query->pluck('Acc_Chl_No');
                $numericValues = $allRecords->filter(function ($value) {
                    return is_numeric($value);
                })->map(function ($value) {
                    return (int)$value;
                });
                $currentMax = $numericValues->max() ?? 0;
                $nextReceiptNumber = $currentMax + 1;
            }

            return response()->json([
                "success" => true,
                "message" => "Voucher status updated successfully",
                "data" => [
                    "CV_No" => $cvNo,
                    "Acc_Chl_No" => $updateData["Acc_Chl_No"] ?? null,
                    "next_receipt_number" => $nextReceiptNumber
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                "success" => false,
                "message" => "Error updating voucher status",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function paymentModeWiseChallan(Request $request): JsonResponse
    {
        try {

            $query = ChlVoucher::query();

            if ($request->filled('Is_income')) {
                $query->where('Is_income', $request->Is_income);
            }

            if ($request->filled('Dpt_Id')) {
                $query->where('Dpt_Id', $request->Dpt_Id);
            }

            if ($request->filled('Py_Mode')) {
                $query->where('Py_Mode', $request->Py_Mode);
            }

            if ($request->filled('search')) {
                $search = $request->search;

                $query->where(function ($q) use ($search) {
                    $q->where('CV_No', 'like', "%$search%")
                        ->orWhere('SL_Nm', 'like', "%$search%");
                });
            }

            $rows = $query->with([
                'department',
                'statusMaster',
                'chequeStatus'
            ])
                ->orderBy('Py_Mode')
                ->orderBy('CV_No')
                ->get()
                ->groupBy('Py_Mode');

            $data = $rows->map(function ($modeItems, $mode) {

                return [
                    "Payment_Mode" => $mode,

                    "challans" => $modeItems->groupBy('CV_No')->map(function ($items) {

                        $header = $items->first();

                        return [
                            "CV_No" => $header->CV_No,
                            "CV_Id" => $header->CV_Id,
                            "Ch_Date" => $header->Ch_Date,
                            "Total_Amount" => $header->Total_Amount,
                            "Net_Amount" => $header->Net_Amount,
                            "Status" => $header->Status,
                            "Is_Cheque_Verf" => $header->Is_Cheque_Verf,
                            "Cheque_Cnl_Remark" => $header->Cheque_Cnl_Remark,
                            "Chq_Status" => $header->Chq_Status,
                            "department" => $header->department ? [
                                "Dpt_Id" => $header->department->Dpt_id ?? null,
                                "Dpt_Name" => $header->department->Dpt_Name ?? null
                            ] : null,
                            "details" => $items->map(function ($row) {
                                return [
                                    "CV_Id" => $row->CV_Id,
                                    "CV_Sr" => $row->CV_Sr,
                                    "SL_Nm" => $row->SL_Nm,
                                    "Amount" => $row->Amount,
                                    "Payment_Mode" => $row->Py_Mode,
                                    "Remarks" => $row->Remarks,
                                    "Chq_No" => $row->Chq_No,
                                    "Bank_Name" => $row->Bank_Name,
                                    "Is_Cheque_Verf" => $row->Is_Cheque_Verf,
                                    "Cheque_Cnl_Remark" => $row->Cheque_Cnl_Remark,
                                    "Chq_Status" => $row->Chq_Status
                                ];
                            })->values()
                        ];
                    })->values()
                ];
            })->values();

            return response()->json([
                "success" => true,
                "message" => "Payment mode wise challan list",
                "data" => $data
            ]);
        } catch (\Exception $e) {

            return response()->json([
                "success" => false,
                "message" => "Error",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function getNextAccChlNo(Request $request)
    {
        $request->validate([
            'dept_id'   => 'nullable',
            'is_income' => 'nullable',
        ]);

        $deptId   = $request->dept_id;
        $isIncome = $request->is_income;

        $query = ChlVoucher::whereNotNull('Acc_Chl_No')
            ->whereNull('deleted_at');

        // 🔥 Department filter
        if (!is_null($deptId)) {
            $query->where('Dpt_Id', $deptId);
        }

        // 🔥 Income / Expense filter
        if (!is_null($isIncome)) {
            $query->where('Is_income', $isIncome);
        }

        // 🔥 Get all Acc_Chl_No values
        $allRecords = $query->pluck('Acc_Chl_No');

        // 🔥 Keep only numeric values
        $numericValues = $allRecords->filter(function ($value) {
            return is_numeric($value);
        })->map(function ($value) {
            return (int) $value;
        });

        // 🔥 Find max number
        $maxAccChlNo = $numericValues->max() ?? 0;

        // 🔥 Next number
        $nextAccChlNo = $maxAccChlNo + 1;

        return response()->json([
            'success'         => true,
            'next_acc_chl_no' => $nextAccChlNo,
            'current_max_no'  => $maxAccChlNo,
            'dept_id'         => $deptId,
            'is_income'       => $isIncome,
        ]);
    }


    public function getNextCVNo(Request $request)
    {
        $request->validate([
            'dept_id'   => 'nullable',
            'is_income' => 'nullable',
        ]);

        $deptId   = $request->dept_id;
        // $isIncome = $request->is_income;

        $query = ChlVoucher::whereNotNull('CV_No')
            ->whereNull('deleted_at');

        if (!is_null($deptId)) {
            $query->where('Dpt_Id', $deptId);
        }

        // if (!is_null($isIncome)) {
        //     $query->where('Is_income', $isIncome);
        // }

        $count = $query->distinct('CV_No')->count('CV_No');

        return response()->json([
            'success'    => true,
            'next_cv_no' => $count + 1,
            'dept_id'    => $deptId,
            // 'is_income'  => $isIncome,
        ]);
    }


    public function updateAccChlNoDirect(Request $request, $id): JsonResponse
    {
        try {

            $request->validate([
                'Status' => 'required|exists:action_master,Act_Id',
                'R_Status' => 'nullable|exists:action_master,Act_Id',
                'Chq_Status' => 'nullable|exists:action_master,Act_Id',
                'Status_Remark' => 'nullable|string|max:500',
                'Acc_Chl_No' => 'nullable|string|max:255',
                'CHl_HOD' => 'nullable|exists:user_master,Usr_Id'
            ]);

            $userId = $request->CHl_HOD ?? $request->UserId ?? auth()->user()->Usr_Id ?? null;

            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {
                return response()->json([
                    "success" => false,
                    "message" => "Voucher not found"
                ], 404);
            }

            $cvNo = $voucher->CV_No;

            $updateData = [
                "Status" => $request->Status,
                "R_Status" => $request->R_Status,
                "Chq_Status" => $request->Chq_Status,
                "Status_Remark" => $request->Status_Remark,
                "CHL_HDT" => now()
            ];

            // ✅ FRONTEND VALUE DIRECT SAVE
            if ($request->filled('Acc_Chl_No')) {
                $updateData["Acc_Chl_No"] = $request->Acc_Chl_No;
                $updateData["Acc_Chl_Date"] = now()->toDateString();
            }

            if ($request->filled('CHl_HOD')) {
                $updateData["CHl_HOD"] = $request->CHl_HOD;
            }

            ChlVoucher::where("CV_No", $cvNo)->update($updateData);

            // Activity log
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                $request->Status,
                $id
            );

            return response()->json([
                "success" => true,
                "message" => "Voucher status updated successfully",
                "data" => [
                    "CV_No" => $cvNo,
                    "Acc_Chl_No" => $updateData["Acc_Chl_No"] ?? null
                ]
            ]);
        } catch (\Exception $e) {
            return response()->json([
                "success" => false,
                "message" => "Error updating voucher status",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    // ==================== HELPER FUNCTION FOR ACTIVITY LOG ====================
    private function storeActivityLog($userId, $menuId, $actionId, $tranId)
    {
        $debugMessage = 'storeActivityLog - userId:' . ($userId ?? 'null') . ' menuId:' . $menuId . ' actionId:' . $actionId . ' tranId:' . $tranId;
        file_put_contents(storage_path('logs/activity_debug.log'), $debugMessage . PHP_EOL, FILE_APPEND);

        if (!$userId) {
            file_put_contents(storage_path('logs/activity_debug.log'), 'User ID is NULL - skipping log' . PHP_EOL, FILE_APPEND);
            return;
        }

        try {
            $log = ActivityLog::create([
                'U_Id' => $userId,
                'Menu_Id' => $menuId,
                'Time_Stamp' => now(),
                'Action_Id' => $actionId,
                'Tran_Id' => $tranId
            ]);

            file_put_contents(storage_path('logs/activity_debug.log'), 'SUCCESS - Log ID: ' . ($log->Act_Log ?? 'unknown') . PHP_EOL, FILE_APPEND);
        } catch (\Exception $e) {
            file_put_contents(storage_path('logs/activity_debug.log'), 'ERROR: ' . 'Something went wrong. Please try again later.' . PHP_EOL, FILE_APPEND);
        }
    }

    // ===================================================================== NEW BULK ===================================================================== //
    public function bulkUpdateVoucherStatus(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'ids'           => 'required|array',
                'ids.*'         => 'exists:chl_voucher,CV_Id',
                'Status'        => 'required|exists:action_master,Act_Id',
                'R_Status'      => 'nullable|exists:action_master,Act_Id',
                'Chq_Status'    => 'nullable|exists:action_master,Act_Id',
                'Status_Remark' => 'nullable|string|max:500',
                'Acc_Chl_No'    => 'nullable|string|max:255',
                'CHl_HOD'       => 'nullable|exists:user_master,Usr_Id',
                'Last_Approval_Date' => 'nullable|date',
            ]);

            $userId = $request->CHl_HOD
                ?? $request->UserId
                ?? auth()->user()->Usr_Id
                ?? null;

            $vouchers = ChlVoucher::whereIn('CV_Id', $request->ids)
                ->get(['CV_No', 'Is_income', 'Acc_Chl_No'])
                ->unique('CV_No');

            $updatedCVNos = [];

            foreach ($vouchers as $voucher) {
                $cvNo     = $voucher->CV_No;
                $isIncome = $voucher->Is_income;

                $updateData = [
                    'Status'        => $request->Status,
                    'R_Status'      => $request->R_Status,
                    'Chq_Status'    => $request->Chq_Status,
                    'Status_Remark' => $request->Status_Remark,
                    'CHL_HDT'       => now(),
                ];

                if ($request->filled('Last_Approval_Date')) {
                    $updateData['Last_Approval_Date'] = $request->Last_Approval_Date;
                }

                if ($request->filled('CHl_HOD')) {
                    $updateData['CHl_HOD'] = $request->CHl_HOD;
                }

                // Only generate Acc_Chl_No if requested AND voucher doesn't already have one
                if (
                    $request->has('Acc_Chl_No')
                    && $request->Acc_Chl_No !== null
                    && !$voucher->Acc_Chl_No
                ) {
                    // Re-query DB each iteration so counter reflects
                    // numbers saved by previous iterations in this loop
                    $maxAccChlNo = ChlVoucher::whereNotNull('Acc_Chl_No')
                        ->whereNull('deleted_at')
                        ->where('Is_income', $isIncome)
                        ->pluck('Acc_Chl_No')
                        ->filter(fn($v) => is_numeric($v))
                        ->map(fn($v) => (int) $v)
                        ->max() ?? 0;

                    $updateData['Acc_Chl_No']   = $maxAccChlNo + 1;
                    $updateData['Acc_Chl_Date'] = now()->toDateString();
                }

                ChlVoucher::where('CV_No', $cvNo)->update($updateData);
                $updatedCVNos[] = $cvNo;

                $relatedIds = ChlVoucher::where('CV_No', $cvNo)->pluck('CV_Id');
                foreach ($relatedIds as $id) {
                    $this->storeActivityLog(
                        $userId,
                        $request->Mod_Code ?? 'CHAL',
                        $request->Status,
                        $id
                    );
                }
            }

            return response()->json([
                'success' => true,
                'message' => 'Bulk voucher status updated successfully',
                'data'    => ['updated_cv_nos' => $updatedCVNos],
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error in bulk update',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage(),
            ], 500);
        }
    }

    public function bulkUpdateVoucherStatusDirect(Request $request): JsonResponse
    {
        try {
            $request->validate([
                'ids'           => 'required|array',
                'ids.*'         => 'exists:chl_voucher,CV_Id',
                'Status'        => 'required|exists:action_master,Act_Id',
                'R_Status'      => 'nullable|exists:action_master,Act_Id',
                'Chq_Status'    => 'nullable|exists:action_master,Act_Id',
                'Status_Remark' => 'nullable|string|max:500',
                'CHl_HOD'       => 'nullable|exists:user_master,Usr_Id',
                'gvn_no'        => 'required',
                'is_income'     => 'nullable|in:Y,N',
                'dept_id'       => 'nullable',
            ]);

            $userId = $request->CHl_HOD
                ?? $request->UserId
                ?? auth()->user()->Usr_Id
                ?? null;

            // Load gen voucher config
            $genVoucherConfig = \App\Models\GenVoucherNo::where('gvn_no', $request->gvn_no)
                ->where('Is_Active', 'Y')
                ->first();

            if (!$genVoucherConfig) {
                return response()->json([
                    'success' => false,
                    'message' => 'Voucher config not found or inactive for gvn_no: ' . $request->gvn_no,
                ], 422);
            }

            // Load current financial year
            $currentFY = \App\Models\FyearMaster::where('is_current_year', true)->first();
            $fyCode    = $currentFY?->FY_Code ?? (date('Y') . '-' . (date('Y') + 1));

            $updatedVouchers = [];

            foreach ($request->ids as $cvId) {
                $voucher = ChlVoucher::with('department')->find($cvId);
                if (!$voucher) continue;

                $updateData = [
                    'Status'        => $request->Status,
                    'R_Status'      => $request->R_Status,
                    'Chq_Status'    => $request->Chq_Status,
                    'Status_Remark' => $request->Status_Remark,
                    'CHL_HDT'       => now(),
                ];

                if ($request->filled('CHl_HOD')) {
                    $updateData['CHl_HOD'] = $request->CHl_HOD;
                }

                $deptId   = $request->dept_id ?? $voucher->Dpt_Id ?? null;
                $deptDesc = $voucher->department?->Dpt_Desc ?? '';
                $isIncome = $request->is_income ?? $voucher->Is_income ?? 'Y';

                // Re-query DB each iteration — picks up numbers saved by previous iterations
                $nextNo = $this->getNextAccChlNoCounterBulk($genVoucherConfig, $deptId, $isIncome);

                $accChlNo = $this->buildAccChlNoFromConfig(
                    $genVoucherConfig,
                    $nextNo,
                    $fyCode,
                    $deptDesc
                );

                $updateData['Acc_Chl_No']   = $accChlNo;
                $updateData['Acc_Chl_Date'] = now()->toDateString();

                ChlVoucher::where('CV_No', $voucher->CV_No)->update($updateData);

                $relatedIds = ChlVoucher::where('CV_No', $voucher->CV_No)->pluck('CV_Id');
                foreach ($relatedIds as $id) {
                    $this->storeActivityLog(
                        $userId,
                        $request->Mod_Code ?? 'CHAL',
                        $request->Status,
                        $id
                    );
                }

                $updatedVouchers[] = [
                    'CV_Id'      => $cvId,
                    'CV_No'      => $voucher->CV_No,
                    'Acc_Chl_No' => $accChlNo,
                ];
            }

            return response()->json([
                'success' => true,
                'message' => 'Bulk voucher status updated successfully',
                'data'    => $updatedVouchers,
            ]);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Error in bulk update',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage(),
            ], 500);
        }
    }

    private function getNextAccChlNoCounterBulk($config, $deptId, $isIncome): int
    {
        $query = ChlVoucher::whereNotNull('Acc_Chl_No')
            ->whereNull('deleted_at');

        // 🔥 Department-wise series
        if ($config->No == 'Dept_Series' && $deptId) {
            $query->where('Dpt_Id', $deptId);
        }

        // 🔥 Income / Expense filter
        if (!is_null($isIncome)) {
            $query->where('Is_income', $isIncome);
        }

        // 🔥 Re-query DB each iteration so counter reflects
        // numbers saved by previous iterations in this loop
        $maxAccChlNo = $query
            ->pluck('Acc_Chl_No')
            ->filter(fn($v) => is_numeric($v))
            ->map(fn($v) => (int) $v)
            ->max() ?? 0;

        return $maxAccChlNo + 1;
    }


    private function buildAccChlNoFromConfig($config, int $serial, string $fyCode, string $deptDesc): string
    {
        $devType = $config->dev_type ?? '/';
        $segs    = [];

        if ($config->prifix) {
            $segs[] = $config->prifix . ($config->prifix_dev_type ?? $devType);
        }

        if ($config->Dept == 'Y' && $deptDesc) {
            $segs[] = $deptDesc . ($config->dept_dev_type ?? $devType);
        }

        if ($config->Text) {
            $segs[] = $config->Text . ($config->text_dev_type ?? $devType);
        }

        $segs[] = (string) $serial;

        if ($config->FY == 'Y') {
            $segs[] = ($config->no_dev_type ?? $devType) . $fyCode;
        }

        return implode('', $segs);
    }


    public function indexNewChallanVoucher(Request $request): JsonResponse
    {
        try {

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

            $query = ChlVoucher::query();

            // =========================================================
            // SEARCH
            // =========================================================
            if (!empty($search)) {

                $query->where(function ($q) use ($search) {

                    $q->where('CV_No', 'like', "%{$search}%")
                        ->orWhere('SL_Nm', 'like', "%{$search}%")
                        ->orWhere('FileNo', 'like', "%{$search}%")
                        ->orWhere('GST_No', 'like', "%{$search}%")

                        ->orWhereHas('department', function ($q2) use ($search) {

                            $q2->where('Dpt_Name', 'like', "%{$search}%");
                        })

                        ->orWhereHas('ledger', function ($q3) use ($search) {

                            $q3->where('Lg_Name', 'like', "%{$search}%");
                        });
                });
            }

            // =========================================================
            // FILTERS
            // =========================================================

            if ($request->filled('Is_income')) {

                $query->where('Is_income', $request->Is_income);
            }

            if ($request->filled('Dpt_Id')) {

                $query->where('Dpt_Id', $request->Dpt_Id);
            }

            if ($request->filled('Status')) {

                $query->whereIn(
                    'Status',
                    array_unique(explode(',', $request->Status))
                );
            }

            if ($request->filled('TnT_Id')) {

                $query->where('TnT_Id', $request->TnT_Id);
            }

            if ($request->filled('CV_Ty')) {

                $query->where('CV_Ty', $request->CV_Ty);
            }

            // =========================================================
            // GET UNIQUE CV_No
            // =========================================================
            $voucherNumbers = $query
                ->select(
                    'CV_No',
                    DB::raw('MAX(Ch_Date) as latest_date')
                )
                ->groupBy('CV_No')
                ->orderByDesc('latest_date')
                ->paginate($perPage);

            // =========================================================
            // FETCH FULL DATA
            // =========================================================
            $rows = ChlVoucher::with([

                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod',
                'statusMaster',
                'tenderType',
                'RStatus',
                'chequeStatus',
                'payModes',
                'payModes.ledger',
                'payDetails'

            ])
                ->whereIn('CV_No', $voucherNumbers->pluck('CV_No'))
                ->orderByDesc('Ch_Date')
                ->get()
                ->groupBy('CV_No');

            // =========================================================
            // FORMAT RESPONSE
            // =========================================================
            $data = $rows->map(function ($items) {

                $header = $items->first();

                return [

                    // =========================================================
                    // HEADER
                    // =========================================================
                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,

                    "TnT_Id" => $header->TnT_Id,
                    "Is_income" => $header->Is_income,

                    "Status" => $header->Status,
                    "R_Status" => $header->R_Status,
                    "Status_Remark" => $header->Status_Remark,

                    "Acc_Chl_No" => $header->Acc_Chl_No,

                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,

                    "CV_Ty" => $header->CV_Ty,
                    "Dpt_Id" => $header->Dpt_Id,

                    "Bh_Id" => $header->Bh_Id,
                    "Lg_Id" => $header->Lg_Id,
                    "SL_Id" => $header->SL_Id,

                    "PayMd_ID" => $header->PayMd_ID,

                    "SL_Nm" => $header->SL_Nm,
                    "Py_Mode" => $header->Py_Mode,

                    "Is_Cheque_Verf" =>
                    $header->Is_Cheque_Verf,

                    "Cheque_Cnl_Remark" =>
                    $header->Cheque_Cnl_Remark,

                    "Chq_Status" => $header->Chq_Status,

                    "Amount" => $header->Amount,

                    "Total_Amount" =>
                    $header->Total_Amount,

                    "Net_Amount" =>
                    $header->Net_Amount,

                    "FileNo" => $header->FileNo,
                    "Remarks" => $header->Remarks,

                    // =========================================================
                    // DATES
                    // =========================================================
                    "Ch_Date" => $header->Ch_Date,

                    "formatted_ch_date" =>
                    $header->Ch_Date
                        ? \Carbon\Carbon::parse($header->Ch_Date)
                        ->format('d-m-Y')
                        : null,

                    "Ch_Start_Date" =>
                    $header->Ch_Start_Date,

                    "formatted_start_date" =>
                    $header->Ch_Start_Date
                        ? \Carbon\Carbon::parse($header->Ch_Start_Date)
                        ->format('d-m-Y')
                        : null,

                    "Ch_End_Date" =>
                    $header->Ch_End_Date,

                    "formatted_end_date" =>
                    $header->Ch_End_Date
                        ? \Carbon\Carbon::parse($header->Ch_End_Date)
                        ->format('d-m-Y')
                        : null,

                    "Acc_Chl_Date" =>
                    $header->Acc_Chl_Date,

                    "formatted_Acc_Chl_Date" =>
                    $header->Acc_Chl_Date
                        ? \Carbon\Carbon::parse($header->Acc_Chl_Date)
                        ->format('d-m-Y')
                        : null,

                    "Chq_Date" => $header->Chq_Date,
                    "Bank_Name" => $header->Bank_Name,
                    "IFSC_Code" => $header->IFSC_Code,
                    "Acc_No" => $header->Acc_No,
                    "Chq_No" => $header->Chq_No,
                    "Rec_Date" => $header->Rec_Date,

                    // =========================================================
                    // DEPARTMENT
                    // =========================================================
                    "department" => $header->department
                        ? [
                            "Dpt_id" =>
                            $header->department->Dpt_id,

                            "Dpt_Name" =>
                            $header->department->Dpt_Name,

                            "Dpt_Code" =>
                            $header->department->Dpt_Code
                        ]
                        : null,

                    // =========================================================
                    // CHALLAN TYPE
                    // =========================================================
                    "challan_type" => $header->challanType
                        ? [
                            "Cht_Id" =>
                            $header->challanType->Cht_Id,

                            "Cht_Name" =>
                            $header->challanType->Cht_Name,

                            "Cht_Code" =>
                            $header->challanType->Cht_Code
                        ]
                        : null,

                    // =========================================================
                    // TENDER TYPE
                    // =========================================================
                    "tender_type" => $header->tenderType
                        ? [
                            "Tnt_Id" =>
                            $header->tenderType->TnT_ID,

                            "Tnt_Code" =>
                            $header->tenderType->TnT_Code,

                            "Tnt_Name" =>
                            $header->tenderType->TnT_Name
                        ]
                        : null,

                    // =========================================================
                    // STATUS MASTER
                    // =========================================================
                    "status_master" => $header->statusMaster
                        ? [
                            "Act_Id" =>
                            $header->statusMaster->Act_Id,

                            "St_Name" =>
                            $header->statusMaster->St_Name
                        ]
                        : null,

                    // =========================================================
                    // RETURN STATUS
                    // =========================================================
                    "return_status" => $header->RStatus
                        ? [
                            "Act_Id" =>
                            $header->RStatus->Act_Id,

                            "St_Name" =>
                            $header->RStatus->St_Name
                        ]
                        : null,

                    // =========================================================
                    // CHEQUE STATUS
                    // =========================================================
                    "cheque_status" => $header->chequeStatus
                        ? [
                            "Act_Id" =>
                            $header->chequeStatus->Act_Id,

                            "St_Name" =>
                            $header->chequeStatus->St_Name
                        ]
                        : null,

                    // =========================================================
                    // HOD
                    // =========================================================
                    "hod" => $header->hod
                        ? [
                            "Usr_Id" =>
                            $header->hod->Usr_Id ?? null,

                            "Usr_Name" =>
                            $header->hod->Usr_Name ?? null,
                        ]
                        : null,

                    // =========================================================
                    // DETAILS
                    // =========================================================
                    "details" => $items->map(function ($row) {

                        return [

                            "CV_Id" => $row->CV_Id,
                            "CV_Sr" => $row->CV_Sr,

                            "Status" => $row->Status,

                            "Lg_Id" => $row->Lg_Id,
                            "Bh_Id" => $row->Bh_Id,
                            "PayMd_ID" => $row->PayMd_ID,

                            "SL_Id" => $row->SL_Id,
                            "SL_Nm" => $row->SL_Nm,

                            "Amount" => $row->Amount,

                            "Py_Mode" => $row->Py_Mode,

                            "FileNo" => $row->FileNo,
                            "Remarks" => $row->Remarks,

                            "GST_No" => $row->GST_No,

                            "Penalty_Amount" =>
                            $row->Penalty_Amount,

                            "Chq_Date" => $row->Chq_Date,
                            "Bank_Name" => $row->Bank_Name,
                            "IFSC_Code" => $row->IFSC_Code,
                            "Acc_No" => $row->Acc_No,
                            "Chq_No" => $row->Chq_No,
                            "Rec_Date" => $row->Rec_Date,

                            // =========================================================
                            // LEDGER
                            // =========================================================
                            "ledger" => [

                                "Lg_Id" =>
                                optional($row->ledger)->Lg_Id,

                                "Lg_Name" =>
                                optional($row->ledger)->Lg_Name,
                            ],

                            // =========================================================
                            // BUDGET HEAD
                            // =========================================================
                            "budget_head" => [

                                "Bh_Id" =>
                                optional($row->budgetHead)->Bh_Id,

                                "Gr_Nm" =>
                                optional($row->budgetHead)->Gr_Nm,
                            ],

                            // =========================================================
                            // SUB LEDGER
                            // =========================================================
                            "sub_ledger" => [

                                "SL_Id" =>
                                optional($row->subLedger)->SL_Id,

                                "SL_Name" =>
                                optional($row->subLedger)->SL_Name,
                            ],

                            // =========================================================
                            // PAY MODE
                            // =========================================================
                            "paymode" => [

                                "PayMd_ID" =>
                                optional($row->payModes)->PayMd_ID,

                                "PayMd_Name" =>
                                optional($row->payModes)->PayMd_Name,

                                "ledger" => [

                                    "Lg_Id" =>
                                    optional(optional($row->payModes)->ledger)->Lg_Id,

                                    "Lg_Name" =>
                                    optional(optional($row->payModes)->ledger)->Lg_Name,
                                ]
                            ],

                            // =========================================================
                            // PAY DETAILS
                            // =========================================================
                            "pay_details" => $row->payDetails->map(function ($pay) {

                                return [

                                    "PD_Id" => $pay->PD_Id,

                                    "CV_Id" => $pay->CV_Id,

                                    "PD_Ty" => $pay->PD_Ty,

                                    "TnT_ID" => $pay->TnT_ID,

                                    "PVD_Sr" => $pay->PVD_Sr,

                                    "VIP_Id" => $pay->VIP_Id,

                                    "IC_Id" => $pay->IC_Id,

                                    "Cht_Id" => $pay->Cht_Id,

                                    "CIP_Id" => $pay->CIP_Id,

                                    "Lg_Id" => $pay->Lg_Id,

                                    "Percent" => $pay->Percent,

                                    "Formula" => $pay->Formula,

                                    "IC_Amt" => $pay->IC_Amt,

                                    "Add_Dedu" => $pay->Add_Dedu,
                                ];
                            })->values()
                        ];
                    })->values()
                ];
            })->values();

            // =========================================================
            // RESPONSE
            // =========================================================
            return response()->json([

                "success" => true,

                "message" =>
                "Challan voucher list fetched successfully",

                "data" => $data,

                "pagination" => [

                    "current_page" =>
                    $voucherNumbers->currentPage(),

                    "per_page" =>
                    $voucherNumbers->perPage(),

                    "total" =>
                    $voucherNumbers->total(),

                    "last_page" =>
                    $voucherNumbers->lastPage(),
                ]
            ]);
        } catch (\Exception $e) {

            return response()->json([

                "success" => false,

                "message" =>
                "Error fetching challan voucher list",

                "error" => 'Something went wrong. Please try again later.'

            ], 500);
        }
    }


    public function storeNewChallanVoucher(Request $request): JsonResponse
    {
        DB::beginTransaction();

        try {

            $request->validate([

                // ================= CHALLAN HEADER =================
                'Ch_Date' => 'nullable|date',
                'Acc_Chl_Date' => 'nullable|date',

                'CV_No' => 'required|string|max:255',

                'TnT_Id' => 'nullable|exists:tender_type,Tnt_Id',
                'Dpt_Id' => 'nullable|exists:dept_master,Dpt_id',
                'CV_Ty' => 'nullable|exists:challan_type,Cht_Id',

                'Total_Amount' => 'nullable|numeric',
                'Net_Amount' => 'nullable|numeric',

                // ================= CHALLAN DETAIL =================
                'Challan_Detail' => 'required|array|min:1',

                'Challan_Detail.*.CV_Sr' => 'nullable|integer',
                'Challan_Detail.*.Lg_Id' => 'nullable|exists:ledger_master,Lg_Id',
                'Challan_Detail.*.Bh_Id' => 'nullable',
                'Challan_Detail.*.PayMd_ID' => 'nullable',

                'Challan_Detail.*.SL_Nm' => 'nullable|string|max:255',
                'Challan_Detail.*.Amount' => 'nullable|numeric',

                'Challan_Detail.*.Py_Mode' => 'nullable|string|max:100',
                'Challan_Detail.*.FileNo' => 'nullable|string|max:255',
                'Challan_Detail.*.Remarks' => 'nullable|string',

                'Challan_Detail.*.GST_No' => 'nullable|string|max:100',
                'Challan_Detail.*.Penalty_Amount' => 'nullable|numeric',

                'Challan_Detail.*.Chq_Date' => 'nullable|date',
                'Challan_Detail.*.Bank_Name' => 'nullable|string|max:255',
                'Challan_Detail.*.IFSC_Code' => 'nullable|string|max:100',
                'Challan_Detail.*.Acc_No' => 'nullable|string|max:100',
                'Challan_Detail.*.Chq_No' => 'nullable|string|max:100',
                'Challan_Detail.*.Rec_Date' => 'nullable|date',

                // ================= PAY DETAILS =================
                'Challan_Detail.*.pay_details' => 'nullable|array',

                'Challan_Detail.*.pay_details.*.PD_Ty' =>
                'nullable|in:TAX,PENLTY',

                'Challan_Detail.*.pay_details.*.TnT_ID' =>
                'nullable|exists:tender_type,TnT_ID',

                'Challan_Detail.*.pay_details.*.Cht_Id' =>
                'nullable|exists:challan_type,Cht_Id',

                'Challan_Detail.*.pay_details.*.CIP_Id' =>
                'nullable|exists:chlnv_parameter,CIP_Id',

                'Challan_Detail.*.pay_details.*.PVD_Sr' =>
                'nullable|integer',

                'Challan_Detail.*.pay_details.*.VIP_Id' =>
                'nullable|exists:vendinv_parameter,VIP_Id',

                'Challan_Detail.*.pay_details.*.IC_Id' =>
                'nullable|exists:invoice_charge_master,IC_Id',

                'Challan_Detail.*.pay_details.*.Lg_Id' =>
                'nullable|exists:ledger_master,Lg_Id',

                'Challan_Detail.*.pay_details.*.Percent' =>
                'nullable|numeric',

                'Challan_Detail.*.pay_details.*.Formula' =>
                'nullable|string',

                'Challan_Detail.*.pay_details.*.IC_Amt' =>
                'nullable|numeric',

                'Challan_Detail.*.pay_details.*.Add_Dedu' =>
                'nullable|numeric',
            ]);

            // ================= USER =================
            $userId = $request->UserId
                ?? auth()->user()->Usr_Id
                ?? null;

            $firstId = null;

            // ================= CREATE CHALLAN =================
            foreach ($request->Challan_Detail as $detail) {

                $voucher = ChlVoucher::create([

                    // ================= HEADER =================
                    "Ch_Date" => $request->Ch_Date ?? null,
                    "Acc_Chl_Date" => $request->Acc_Chl_Date ?? null,

                    "CV_No" => $request->CV_No ?? null,

                    "TnT_Id" => $request->TnT_Id ?? null,

                    "SL_Id" => $request->SL_Id ?? null,

                    "Total_Amount" => $request->Total_Amount ?? null,
                    "Net_Amount" => $request->Net_Amount ?? null,

                    "Dpt_Id" => $request->Dpt_Id ?? null,
                    "CV_Ty" => $request->CV_Ty ?? null,

                    "Is_income" => $request->Is_income ?? null,

                    "Is_Cheque_Verf" =>
                    $request->Is_Cheque_Verf ?? 'N',

                    "Cheque_Cnl_Remark" =>
                    $request->Cheque_Cnl_Remark ?? null,

                    // ================= DETAIL =================
                    "CV_Sr" => $detail['CV_Sr'] ?? null,
                    "Lg_Id" => $detail['Lg_Id'] ?? null,
                    "Bh_Id" => $detail['Bh_Id'] ?? null,
                    "SL_Id" => $detail['SL_Id'] ?? null,
                    "PayMd_ID" => $detail['PayMd_ID'] ?? null,

                    "SL_Nm" => $detail['SL_Nm'] ?? null,
                    "Amount" => $detail['Amount'] ?? null,

                    "Py_Mode" => $detail['Py_Mode'] ?? null,
                    "FileNo" => $detail['FileNo'] ?? null,
                    "Remarks" => $detail['Remarks'] ?? null,

                    "GST_No" => $detail['GST_No'] ?? null,
                    "Penalty_Amount" =>
                    $detail['Penalty_Amount'] ?? null,

                    "Chq_Date" => $detail['Chq_Date'] ?? null,
                    "Bank_Name" => $detail['Bank_Name'] ?? null,
                    "IFSC_Code" => $detail['IFSC_Code'] ?? null,
                    "Acc_No" => $detail['Acc_No'] ?? null,
                    "Chq_No" => $detail['Chq_No'] ?? null,

                    "Rec_Date" => $detail['Rec_Date'] ?? null,

                    "Chq_Status" =>
                    $request->Chq_Status ?? null,

                    "Status" =>
                    $request->Status ?? null,

                    "CHl_HOD" => null,
                    "CHL_HDT" => null,

                    "created_at" => now(),
                    "updated_at" => now(),
                ]);

                // ================= FIRST ID =================
                if (!$firstId) {
                    $firstId = $voucher->CV_Id;
                }

                // ================= CREATE PAY DETAILS =================
                if (!empty($detail['pay_details'])) {

                    foreach ($detail['pay_details'] as $payDetail) {

                        PayDetail::create([

                            'CV_Id' => $voucher->CV_Id,

                            'PD_Ty' =>
                            $payDetail['PD_Ty'] ?? null,

                            'TnT_ID' =>
                            $payDetail['TnT_ID'] ?? null,

                            'PVD_Sr' =>
                            $payDetail['PVD_Sr'] ?? null,

                            'VIP_Id' =>
                            $payDetail['VIP_Id'] ?? null,

                            'IC_Id' =>
                            $payDetail['IC_Id'] ?? null,

                            'Cht_Id' =>
                            $payDetail['Cht_Id'] ?? null,

                            'CIP_Id' =>
                            $payDetail['CIP_Id'] ?? null,

                            'Lg_Id' =>
                            $payDetail['Lg_Id'] ?? null,

                            'SL_Id' =>
                            $payDetail['SL_Id'] ?? null,

                            'Percent' =>
                            $payDetail['Percent'] ?? null,

                            'Formula' =>
                            $payDetail['Formula'] ?? null,

                            'IC_Amt' =>
                            $payDetail['IC_Amt'] ?? null,

                            'Add_Dedu' =>
                            $payDetail['Add_Dedu'] ?? null,
                        ]);
                    }
                }
            }

            // ================= ACTIVITY LOG =================

            Log::info('Check', [
                'userId' => $userId,
                'Mod_Code' => $request->Mod_Code,
                'Status' => $request->Status,
                'firstId' => $firstId

            ]);

            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                $request->Status ?? null,
                $firstId
            );

            DB::commit();

            return response()->json([
                "success" => true,
                "message" => "Challan created successfully",
                "CV_Id" => $firstId
            ]);
        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json([
                "success" => false,
                "message" => "Error creating challan",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }





    public function showNewChallanVoucher($id): JsonResponse
    {
        try {

            // =========================================================
            // FIND VOUCHER
            // =========================================================
            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {

                return response()->json([
                    "success" => false,
                    "message" => "Challan voucher not found"
                ], 404);
            }

            // =========================================================
            // FETCH ALL ROWS
            // =========================================================
            $rows = ChlVoucher::with([

                'challanType',
                'department',
                'budgetHead',
                'ledger',
                'subLedger',
                'hod',
                'statusMaster',
                'tenderType',
                'RStatus',
                'chequeStatus',
                'payModes',
                'payModes.ledger',
                'payDetails' => function ($q) {
                    $q->whereNull('deleted_at');
                },
                'payDetails.tenderType',
                'payDetails.vendorParameter',
                'payDetails.invoiceCharge',
                'payDetails.ledger',
            ])
                ->where('CV_No', $voucher->CV_No)
                ->orderBy('CV_Sr')
                ->get()
                ->groupBy('CV_No');

            if ($rows->isEmpty()) {

                return response()->json([
                    "success" => false,
                    "message" => "No challan voucher data found"
                ], 404);
            }

            // =========================================================
            // FORMAT RESPONSE
            // =========================================================
            $data = $rows->map(function ($items) {

                $header = $items->first();

                return [

                    // =========================================================
                    // HEADER
                    // =========================================================
                    "CV_Id" => $header->CV_Id,
                    "CV_No" => $header->CV_No,

                    "TnT_Id" => $header->TnT_Id,

                    "Is_income" => $header->Is_income,

                    "Status" => $header->Status,
                    "R_Status" => $header->R_Status,

                    "Status_Remark" => $header->Status_Remark,

                    "Acc_Chl_No" => $header->Acc_Chl_No,

                    "CHl_HOD" => $header->CHl_HOD,
                    "CHL_HDT" => $header->CHL_HDT,

                    "CV_Ty" => $header->CV_Ty,

                    "Dpt_Id" => $header->Dpt_Id,

                    "Bh_Id" => $header->Bh_Id,

                    "Lg_Id" => $header->Lg_Id,

                    "SL_Id" => $header->SL_Id,

                    "PayMd_ID" => $header->PayMd_ID,

                    "SL_Nm" => $header->SL_Nm,

                    "Py_Mode" => $header->Py_Mode,

                    "Is_Cheque_Verf" => $header->Is_Cheque_Verf,

                    "Cheque_Cnl_Remark" =>
                    $header->Cheque_Cnl_Remark,

                    "Chq_Status" => $header->Chq_Status,

                    "Amount" => $header->Amount,

                    "Total_Amount" => $header->Total_Amount,

                    "Net_Amount" => $header->Net_Amount,

                    "FileNo" => $header->FileNo,

                    "Remarks" => $header->Remarks,

                    "Ch_Date" => $header->Ch_Date,

                    "formatted_ch_date" =>
                    $header->Ch_Date
                        ? \Carbon\Carbon::parse($header->Ch_Date)
                        ->format('d-m-Y')
                        : null,

                    "Ch_Start_Date" => $header->Ch_Start_Date,

                    "formatted_start_date" =>
                    $header->Ch_Start_Date
                        ? \Carbon\Carbon::parse($header->Ch_Start_Date)
                        ->format('d-m-Y')
                        : null,

                    "Ch_End_Date" => $header->Ch_End_Date,

                    "formatted_end_date" =>
                    $header->Ch_End_Date
                        ? \Carbon\Carbon::parse($header->Ch_End_Date)
                        ->format('d-m-Y')
                        : null,

                    "Acc_Chl_Date" => $header->Acc_Chl_Date,

                    "formatted_Acc_Chl_Date" =>
                    $header->Acc_Chl_Date
                        ? \Carbon\Carbon::parse($header->Acc_Chl_Date)
                        ->format('d-m-Y')
                        : null,

                    "Chq_Date" => $header->Chq_Date,

                    "Bank_Name" => $header->Bank_Name,

                    "IFSC_Code" => $header->IFSC_Code,

                    "Acc_No" => $header->Acc_No,

                    "Chq_No" => $header->Chq_No,

                    "Rec_Date" => $header->Rec_Date,

                    // =========================================================
                    // RELATIONS
                    // =========================================================

                    "department" => $header->department
                        ? [
                            "Dpt_id" =>
                            $header->department->Dpt_id,

                            "Dpt_Name" =>
                            $header->department->Dpt_Name,

                            "Dpt_Code" =>
                            $header->department->Dpt_Code
                        ]
                        : null,

                    "challan_type" => $header->challanType
                        ? [
                            "Cht_Id" =>
                            $header->challanType->Cht_Id,

                            "Cht_Name" =>
                            $header->challanType->Cht_Name,

                            "Cht_Code" =>
                            $header->challanType->Cht_Code
                        ]
                        : null,

                    "tender_type" => $header->tenderType
                        ? [
                            "TnT_ID" =>
                            $header->tenderType->TnT_ID,

                            "TnT_Code" =>
                            $header->tenderType->TnT_Code,

                            "TnT_Name" =>
                            $header->tenderType->TnT_Name
                        ]
                        : null,

                    "status_master" => $header->statusMaster
                        ? [
                            "Act_Id" =>
                            $header->statusMaster->Act_Id,

                            "St_Name" =>
                            $header->statusMaster->St_Name
                        ]
                        : null,

                    "RStatus" => $header->RStatus
                        ? [
                            "Act_Id" =>
                            $header->RStatus->Act_Id,

                            "St_Name" =>
                            $header->RStatus->St_Name
                        ]
                        : null,

                    "cheque_status" => $header->chequeStatus
                        ? [
                            "Act_Id" =>
                            $header->chequeStatus->Act_Id,

                            "St_Name" =>
                            $header->chequeStatus->St_Name
                        ]
                        : null,

                    "HOD_User" => $header->hod
                        ? [
                            "Usr_Id" =>
                            $header->hod->Usr_Id,

                            "Usr_Name" =>
                            $header->hod->Usr_Name ?? null
                        ]
                        : null,



                    // =========================================================
                    // DETAILS
                    // =========================================================

                    "details" => $items->map(function ($row) {

                        return [

                            "CV_Id" => $row->CV_Id,

                            "CV_Sr" => $row->CV_Sr,

                            "Status" => $row->Status,

                            "Lg_Id" => $row->Lg_Id,

                            "Bh_Id" => $row->Bh_Id,

                            "SL_Id" => $row->SL_Id,

                            "PayMd_ID" => $row->PayMd_ID,

                            "SL_Nm" => $row->SL_Nm,

                            "Amount" => $row->Amount,

                            "Payment_Mode" => $row->Py_Mode,

                            "FileNo" => $row->FileNo,

                            "Remarks" => $row->Remarks,

                            "Penalty_Amount" =>
                            $row->Penalty_Amount,

                            "GST_No" => $row->GST_No,

                            "Chq_Date" => $row->Chq_Date,

                            "Bank_Name" => $row->Bank_Name,

                            "IFSC_Code" => $row->IFSC_Code,

                            "Acc_No" => $row->Acc_No,

                            "Chq_No" => $row->Chq_No,

                            "Rec_Date" => $row->Rec_Date,

                            "Is_Cheque_Verf" =>
                            $row->Is_Cheque_Verf,

                            "Cheque_Cnl_Remark" =>
                            $row->Cheque_Cnl_Remark,

                            "Chq_Status" => $row->Chq_Status,

                            "ledger" => [

                                "Lg_Id" =>
                                optional($row->ledger)->Lg_Id,

                                "Lg_Name" =>
                                optional($row->ledger)->Lg_Name
                            ],

                            "budget_head" => [

                                "Bh_Id" =>
                                optional($row->budgetHead)->Bh_Id,

                                "Gr_Nm" =>
                                optional($row->budgetHead)->Gr_Nm
                            ],

                            "sub_ledger" => [

                                "SL_Id" =>
                                optional($row->subLedger)->SL_Id,

                                "SL_Name" =>
                                optional($row->subLedger)->SL_Name
                            ],

                            "paymode" => [

                                "PayMd_ID" =>
                                optional($row->payModes)->PayMd_ID,

                                "PayMd_Name" =>
                                optional($row->payModes)->PayMd_Name,

                                "ledger" => [

                                    "Lg_Id" =>
                                    optional(optional($row->payModes)->ledger)->Lg_Id,

                                    "Lg_Name" =>
                                    optional(optional($row->payModes)->ledger)->Lg_Name,
                                ]
                            ],

                            // =========================================================
                            // PAY DETAILS
                            // =========================================================
                            "pay_details" => $row->payDetails->map(function ($pay) {

                                return [

                                    "PVD_Id" => $pay->PVD_Id,

                                    "PV_Id" => $pay->PV_Id,

                                    "PD_Ty" => $pay->PD_Ty,

                                    "TnT_ID" => $pay->TnT_ID,

                                    "PVD_Sr" => $pay->PVD_Sr,

                                    "VIP_Id" => $pay->VIP_Id,

                                    "IC_Id" => $pay->IC_Id,

                                    "Cht_Id" => $pay->Cht_Id,

                                    "CIP_Id" => $pay->CIP_Id,

                                    "Lg_Id" => $pay->Lg_Id,

                                    "SL_Id" => $pay->SL_Id,

                                    "Percent" => $pay->Percent,

                                    "Formula" => $pay->Formula,

                                    "IC_Amt" => $pay->IC_Amt,

                                    "Add_Dedu" => $pay->Add_Dedu,

                                    // =====================================================
                                    // TENDER TYPE
                                    // =====================================================
                                    "tender_type" => $pay->tenderType
                                        ? [
                                            "TnT_ID" => $pay->tenderType->TnT_ID,
                                            "TnT_Code" => $pay->tenderType->TnT_Code,
                                            "TnT_Name" => $pay->tenderType->TnT_Name,
                                        ]
                                        : null,

                                    // =====================================================
                                    // VENDOR PARAMETER
                                    // =====================================================
                                    "vendor_parameter" => $pay->vendorParameter
                                        ? [
                                            "VIP_Id" => $pay->vendorParameter->VIP_Id,
                                            "VIP_Name" => $pay->vendorParameter->VIP_Name ?? null,
                                        ]
                                        : null,

                                    // =====================================================
                                    // INVOICE CHARGE
                                    // =====================================================
                                    "invoice_charge" => $pay->invoiceCharge
                                        ? [
                                            "IC_Id" => $pay->invoiceCharge->IC_Id,
                                            "IC_Name" => $pay->invoiceCharge->IC_Name ?? null,
                                        ]
                                        : null,

                                    // =====================================================
                                    // LEDGER
                                    // =====================================================

                                    "ledger" => $pay->ledger
                                        ? [
                                            "Lg_Id" => $pay->ledger->Lg_Id,
                                            "Lg_Name" => $pay->ledger->Lg_Name ?? null,
                                        ]
                                        : null,


                                    // =====================================================
                                    // SUB LEDGER
                                    // =====================================================

                                    "subLedger" => $pay->subLedger
                                        ? [
                                            "SL_Id" => $pay->subLedger->SL_Id,
                                            "SL_Name" => $pay->subLedger->SL_Name ?? null,
                                        ]
                                        : null,

                                    // =====================================================
                                    // CHALLAN PARAMETER
                                    // =====================================================
                                    "challan_parameter" => $pay->ChlnvParameter
                                        ? [
                                            "CIP_Id" => $pay->ChlnvParameter->CIP_Id,
                                            "CIP_Name" => $pay->ChlnvParameter->CIP_Name ?? null,
                                        ]
                                        : null,
                                ];
                            })->values()
                        ];
                    })->values()
                ];
            })->values();

            // =========================================================
            // RESPONSE
            // =========================================================

            return response()->json([

                "success" => true,

                "message" =>
                "Challan voucher fetched successfully",

                "data" => $data

            ]);
        } catch (\Exception $e) {

            return response()->json([

                "success" => false,

                "message" =>
                "Error fetching challan voucher",

                "error" => 'Something went wrong. Please try again later.'

            ], 500);
        }
    }


    public function updateNewChallanVoucher(Request $request, $id): JsonResponse
    {
        DB::beginTransaction();

        try {

            $request->validate([

                // ================= HEADER =================
                'Ch_Date' => 'nullable|date',
                'Acc_Chl_Date' => 'nullable|date',

                'CV_No' => 'required|string|max:255',

                'TnT_Id' => 'nullable|exists:tender_type,Tnt_Id',
                'Dpt_Id' => 'nullable|exists:dept_master,Dpt_id',
                'CV_Ty' => 'nullable|exists:challan_type,Cht_Id',

                'Total_Amount' => 'nullable|numeric',
                'Net_Amount' => 'nullable|numeric',

                // ================= DETAIL =================
                'Challan_Detail' => 'required|array|min:1',
            ]);

            // 🔍 Find voucher
            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {

                return response()->json([
                    "success" => false,
                    "message" => "Challan voucher not found"
                ], 404);
            }

            // ================= USER =================
            $userId = $request->UserId
                ?? auth()->user()->Usr_Id
                ?? null;

            $cvNo = $voucher->CV_No;

            // ================= OLD ROWS =================
            $oldRows = ChlVoucher::where('CV_No', $cvNo)->get();

            // ================= DELETE OLD PAY DETAILS =================
            $oldCvIds = $oldRows->pluck('CV_Id');

            PayDetail::whereIn('CV_Id', $oldCvIds)->delete();

            // ================= DELETE OLD CHALLAN =================
            ChlVoucher::where('CV_No', $cvNo)->delete();

            $firstId = null;

            // ================= RE-CREATE DATA =================
            foreach ($request->Challan_Detail as $index => $detail) {

                $old = $oldRows[$index] ?? null;

                // ================= CREATE CHALLAN =================
                $newVoucher = ChlVoucher::create([

                    // ================= HEADER =================
                    "Ch_Date" => $request->Ch_Date ?? $old->Ch_Date ?? null,

                    "Acc_Chl_Date" =>
                    $request->Acc_Chl_Date
                        ?? $old->Acc_Chl_Date
                        ?? null,

                    "CV_No" => $request->CV_No ?? $old->CV_No ?? null,

                    "TnT_Id" =>
                    $request->TnT_Id
                        ?? $old->TnT_Id
                        ?? null,

                    "Dpt_Id" =>
                    $request->Dpt_Id
                        ?? $old->Dpt_Id
                        ?? null,

                    "CV_Ty" =>
                    $request->CV_Ty
                        ?? $old->CV_Ty
                        ?? null,

                    "Total_Amount" =>
                    $request->Total_Amount
                        ?? $old->Total_Amount
                        ?? null,

                    "Net_Amount" =>
                    $request->Net_Amount
                        ?? $old->Net_Amount
                        ?? null,

                    "Is_income" =>
                    $request->Is_income
                        ?? $old->Is_income
                        ?? null,

                    "Is_Cheque_Verf" =>
                    $request->Is_Cheque_Verf
                        ?? $old->Is_Cheque_Verf
                        ?? 'N',

                    "Cheque_Cnl_Remark" =>
                    $request->Cheque_Cnl_Remark
                        ?? $old->Cheque_Cnl_Remark
                        ?? null,

                    "Chq_Status" =>
                    $request->Chq_Status
                        ?? $old->Chq_Status
                        ?? null,

                    "Status" =>
                    $request->Status
                        ?? $old->Status
                        ?? 'draft',

                    // ================= DETAIL =================
                    "CV_Sr" =>
                    $detail['CV_Sr']
                        ?? $old->CV_Sr
                        ?? null,

                    "Lg_Id" =>
                    $detail['Lg_Id']
                        ?? $old->Lg_Id
                        ?? null,

                    "Bh_Id" =>
                    $detail['Bh_Id']
                        ?? $old->Bh_Id
                        ?? null,

                    "SL_Id" =>
                    $detail['SL_Id']
                        ?? $old->SL_Id
                        ?? null,

                    "PayMd_ID" =>
                    $detail['PayMd_ID']
                        ?? $old->PayMd_ID
                        ?? null,

                    "SL_Nm" =>
                    $detail['SL_Nm']
                        ?? $old->SL_Nm
                        ?? null,

                    "Amount" =>
                    $detail['Amount']
                        ?? $old->Amount
                        ?? null,

                    "Py_Mode" =>
                    $detail['Py_Mode']
                        ?? $old->Py_Mode
                        ?? null,

                    "FileNo" =>
                    $detail['FileNo']
                        ?? $old->FileNo
                        ?? null,

                    "Remarks" =>
                    $detail['Remarks']
                        ?? $old->Remarks
                        ?? null,

                    "GST_No" =>
                    $detail['GST_No']
                        ?? $old->GST_No
                        ?? null,

                    "Penalty_Amount" =>
                    $detail['Penalty_Amount']
                        ?? $old->Penalty_Amount
                        ?? null,

                    "Chq_Date" =>
                    $detail['Chq_Date']
                        ?? $old->Chq_Date
                        ?? null,

                    "Bank_Name" =>
                    $detail['Bank_Name']
                        ?? $old->Bank_Name
                        ?? null,

                    "IFSC_Code" =>
                    $detail['IFSC_Code']
                        ?? $old->IFSC_Code
                        ?? null,

                    "Acc_No" =>
                    $detail['Acc_No']
                        ?? $old->Acc_No
                        ?? null,

                    "Chq_No" =>
                    $detail['Chq_No']
                        ?? $old->Chq_No
                        ?? null,

                    "Rec_Date" =>
                    $detail['Rec_Date']
                        ?? $old->Rec_Date
                        ?? null,

                    "CHl_HOD" => $old->CHl_HOD ?? null,
                    "CHL_HDT" => $old->CHL_HDT ?? null,

                    "created_at" => $old->created_at ?? now(),
                    "updated_at" => now(),
                ]);

                // ✅ First ID
                if (!$firstId) {
                    $firstId = $newVoucher->CV_Id;
                }

                // ================= PAY DETAILS =================
                if (!empty($detail['pay_details'])) {

                    foreach ($detail['pay_details'] as $payDetail) {

                        PayDetail::create([

                            'CV_Id' => $newVoucher->CV_Id,

                            'PD_Ty' =>
                            $payDetail['PD_Ty'] ?? null,

                            'TnT_ID' =>
                            $payDetail['TnT_ID'] ?? null,

                            'PVD_Sr' =>
                            $payDetail['PVD_Sr'] ?? null,

                            'VIP_Id' =>
                            $payDetail['VIP_Id'] ?? null,

                            'IC_Id' =>
                            $payDetail['IC_Id'] ?? null,

                            'Cht_Id' =>
                            $payDetail['Cht_Id'] ?? null,

                            'CIP_Id' =>
                            $payDetail['CIP_Id'] ?? null,

                            'Lg_Id' =>
                            $payDetail['Lg_Id'] ?? null,

                            'SL_Id' =>
                            $payDetail['SL_Id'] ?? null,

                            'Percent' =>
                            $payDetail['Percent'] ?? null,

                            'Formula' =>
                            $payDetail['Formula'] ?? null,

                            'IC_Amt' =>
                            $payDetail['IC_Amt'] ?? null,

                            'Add_Dedu' =>
                            $payDetail['Add_Dedu'] ?? null,
                        ]);
                    }
                }
            }

            // ================= ACTIVITY LOG =================
            $this->storeActivityLog(
                $userId,
                $request->Mod_Code ?? 'CHAL',
                13,
                $firstId
            );

            DB::commit();

            return response()->json([
                "success" => true,
                "message" => "Challan voucher updated successfully",
                "CV_Id" => $firstId
            ]);
        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json([
                "success" => false,
                "message" => "Error updating challan voucher",
                "error" => 'Something went wrong. Please try again later.'
            ], 500);
        }
    }


    public function deleteNewChallanVoucher($id): JsonResponse
    {
        DB::beginTransaction();

        try {

            // =====================================================
            // FIND MAIN VOUCHER
            // =====================================================
            $voucher = ChlVoucher::where('CV_Id', $id)->first();

            if (!$voucher) {

                return response()->json([
                    "success" => false,
                    "message" => "Challan voucher not found"
                ], 404);
            }

            // =====================================================
            // GET ALL CHALLAN ROWS OF SAME CV_NO
            // =====================================================
            $challanRows = ChlVoucher::where(
                'CV_No',
                $voucher->CV_No
            )->get();

            // =====================================================
            // GET ALL CV IDs
            // =====================================================
            $cvIds = $challanRows->pluck('CV_Id');

            // =====================================================
            // SOFT DELETE PAY DETAILS
            // =====================================================
            PayDetail::whereIn('CV_Id', $cvIds)->delete();

            // =====================================================
            // SOFT DELETE CHALLAN ROWS
            // =====================================================
            ChlVoucher::whereIn('CV_Id', $cvIds)->delete();

            DB::commit();

            return response()->json([

                "success" => true,

                "message" =>
                "Challan voucher and pay details deleted successfully"
            ]);
        } catch (\Exception $e) {

            DB::rollBack();

            return response()->json([

                "success" => false,

                "message" =>
                "Error deleting challan voucher",

                "error" => 'Something went wrong. Please try again later.'

            ], 500);
        }
    }



    public function bankPaymentReport(Request $request)
    {
        try {

            $query = ChlVoucher::with([
                'subLedger',
                'payModes',
                'payModes.ledger'
            ])
                ->withSum([
                    'payDetails as add_amount' => function ($q) {
                        $q->where('Add_Dedu', 1);
                    }
                ], 'IC_Amt')
                ->withSum([
                    'payDetails as deduct_amount' => function ($q) {
                        $q->where('Add_Dedu', 0);
                    }
                ], 'IC_Amt');

            // Is_Income Filter
            if ($request->filled('Is_income')) {
                $value = trim($request->Is_income);

                if (in_array(strtolower($value), ['income', 'yes', 'true', '1', 'y'])) {
                    $query->where('Is_income', 'Y');
                } elseif (in_array(strtolower($value), ['expense', 'no', 'false', '0', 'n'])) {
                    $query->where('Is_income', 'N');
                } else {
                    $query->where('Is_income', $value);
                }
            }

            // Status Filter
            if ($request->filled('status')) {
                $query->where('Status', $request->status);
            }

            // Payment Mode Filter
            if ($request->filled('PayMd_ID')) {
                $query->where('PayMd_ID', $request->PayMd_ID);
            }

            // Date Filters
            if ($request->filled('start_date')) {
                $query->whereDate('Last_Approval_Date', '>=', $request->start_date);
            }

            if ($request->filled('end_date')) {
                $query->whereDate('Last_Approval_Date', '<=', $request->end_date);
            }

            $vouchers = $query
                ->orderBy('CV_Id', 'DESC')
                ->get();

            $data = $vouchers->map(function ($voucher, $index) {

                $baseAmount = (float) ($voucher->Amount ?? 0);

                $addAmount = (float) ($voucher->add_amount ?? 0);

                $deductAmount = (float) ($voucher->deduct_amount ?? 0);

                $payableAmount = $baseAmount + $addAmount - $deductAmount;

                return [
                    'SrNo' => $index + 1,
                    'CV_Id' => $voucher->CV_Id,

                    'Amount' => $baseAmount,
                    'Add_Amount' => $addAmount,
                    'Deduct_Amount' => $deductAmount,

                    'Payable_Amount' => number_format($payableAmount, 2, '.', ''),

                    'tran_date' => now()->format('Y-m-d'),

                    'PayMd_ID' => $voucher->PayMd_ID,
                    'Payment_Mode' => $voucher->Py_Mode,

                    'LG_Id' => optional($voucher->payModes)->Lg_Id,
                    'LG_Name' => optional(optional($voucher->payModes)->ledger)->Lg_Name,

                    'IFSC' => $voucher->IFSC_Code,
                    'acc_no' => $voucher->Acc_No,

                    'SL_Id' => $voucher->SL_Id,
                    'SL_Name' => optional($voucher->subLedger)->SL_Name ?? $voucher->SL_Nm,

                    'vouchar_no' => $voucher->CV_No,
                    'Acc_Chall_no' => $voucher->Acc_Chl_No,

                    'Bank_Name' => $voucher->Bank_Name,
                    'Chq_No' => $voucher->Chq_No,
                    'Chq_Date' => $voucher->Chq_Date,

                    'Ch_Date' => $voucher->Ch_Date,

                    'Status' => $voucher->Status,

                    'Is_income' => $voucher->getOriginal('Is_income') ?? $voucher->Is_income,
                ];
            });

            return response()->json([
                'success' => true,
                'filters' => [
                    'Is_income' => $request->Is_income,
                    'status' => $request->status,
                    'PayMd_ID' => $request->PayMd_ID,
                    'start_date' => $request->start_date,
                    'end_date' => $request->end_date,
                ],
                'count' => $data->count(),
                'data' => $data
            ]);
        } catch (\Exception $e) {

            return response()->json([
                'success' => false,
                'message' => 'Something went wrong. Please try again later.',
                'line' => $e->getLine()
            ], 500);
        }
    }


public function bankPaymentrecieptreport(Request $request)
{
    try {

        $query = ChlVoucher::with([
            'subLedger',
            'payDetails',
            'payDetails.ledger'
        ])
        ->withSum([
            'payDetails as add_amount' => function ($q) {
                $q->where('Add_Dedu', 1);
            }
        ], 'IC_Amt')
        ->withSum([
            'payDetails as deduct_amount' => function ($q) {
                $q->where('Add_Dedu', 0);
            }
        ], 'IC_Amt')
        ->where('Is_income', 'N')

        // Avoid records where Voucher No (Acc_Chl_No) is null or empty
        ->whereNotNull('Acc_Chl_No')
        ->where('Acc_Chl_No', '!=', '');

        // Date Filters
        if ($request->filled('start_date')) {
            $query->whereDate('Acc_Chl_Date', '>=', $request->start_date);
        }

        if ($request->filled('end_date')) {
            $query->whereDate('Acc_Chl_Date', '<=', $request->end_date);
        }

        // Status Filter
        if ($request->filled('status')) {
            $query->where('Status', $request->status);
        }

        $vouchers = $query
            // ->orderBy('Acc_Chl_No', 'ASC')
            ->orderByRaw('CAST(Acc_Chl_No AS UNSIGNED) ASC')
            ->get();

        $data = $vouchers->map(function ($voucher, $index) {

            $billAmount = (float) ($voucher->Amount ?? 0);

            $addAmount = (float) ($voucher->add_amount ?? 0);

            $deductAmount = (float) ($voucher->deduct_amount ?? 0);

            // Cheque Amount = Bill Amount + Add - Deduct
            $chequeAmount = $billAmount + $addAmount - $deductAmount;

            // Deduction Heads
            $deductionHeads = $voucher->payDetails
                ->where('Add_Dedu', 0)
                ->map(function ($detail) {
                    return [
                        'Deduction_Head' => optional($detail->ledger)->Lg_Name,
                        'Amount' => (float) ($detail->IC_Amt ?? 0)
                    ];
                })
                ->values();

            return [
                'SrNo' => $index + 1,

                // Voucher No
                'Voucher_No' => $voucher->Acc_Chl_No,

                // Trans. Date
                'Trans_Date' => $voucher->Acc_Chl_Date,

                // Party Name
                'Party_Name' => optional($voucher->subLedger)->SL_Name ?? $voucher->SL_Nm,

                // Bill No
                'Bill_No' => $voucher->CV_No,

                // Cheque No
                'Cheque' => $voucher->Chq_No,

                // Bill Amount
                'Bill_Amount' => number_format($billAmount, 2, '.', ''),

                // Cheque Amount
                'Cheque_Amount' => number_format($chequeAmount, 2, '.', ''),

                // Deduction Head | Amount
                'Deduction_Head_Amount' => $deductionHeads,
            ];
        });

        return response()->json([
            'success' => true,

            'report_period' => [
                'from' => $request->start_date,
                'to' => $request->end_date
            ],

            'count' => $data->count(),

            'total_bill_amount' => number_format(
                $data->sum(fn($row) => (float) $row['Bill_Amount']),
                2,
                '.',
                ''
            ),

            'total_cheque_amount' => number_format(
                $data->sum(fn($row) => (float) $row['Cheque_Amount']),
                2,
                '.',
                ''
            ),

            'data' => $data
        ]);

    } catch (\Exception $e) {

        return response()->json([
            'success' => false,
            'message' => 'Something went wrong. Please try again later.',
            'line' => $e->getLine()
        ], 500);
    }
}
}
