<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;

class PurchaseBillingVehicleRegisterController extends Controller
{
    protected string $module = 'Reports Management';

    public function __construct()
    {
        $module = $this->module;
        // $this->middleware("permission:$module Purchase Billing Vehicle Register")->only(['index']);
    }

    public function index(Request $request)
    {
        $dateFrom   = $request->input('date_from', now()->startOfMonth()->toDateString());
        $dateTo     = $request->input('date_to',   now()->toDateString());
        $supplierId = $request->input('supplier_id');
        $vehicleNo  = $request->input('vehicle_no');

        $reportData = null;

        if ($request->hasAny(['date_from', 'date_to', 'supplier_id', 'vehicle_no'])) {
            $reportData = $this->buildReport($dateFrom, $dateTo, $supplierId, $vehicleNo);
        }

        $suppliers = DB::table('suppliers')
            ->select('id_supplier', 'supplier_name')
            ->orderBy('supplier_name')
            ->get();

        return view('reports.purchase_billing_vehicle_register_report', compact(
            'dateFrom', 'dateTo', 'supplierId', 'vehicleNo', 'suppliers', 'reportData'
        ));
    }

    public function print(Request $request)
    {
        $dateFrom   = $request->input('date_from', now()->startOfMonth()->toDateString());
        $dateTo     = $request->input('date_to',   now()->toDateString());
        $supplierId = $request->input('supplier_id');
        $vehicleNo  = $request->input('vehicle_no');

        $reportData = $this->buildReport($dateFrom, $dateTo, $supplierId, $vehicleNo);

        $supplierName = null;
        if ($supplierId) {
            $supplierName = DB::table('suppliers')
                ->where('id_supplier', $supplierId)
                ->value('supplier_name');
        }

        return view('reports.purchase_billing_vehicle_register_print_view', compact(
            'dateFrom', 'dateTo', 'supplierId', 'supplierName', 'vehicleNo', 'reportData'
        ));
    }

    // ─────────────────────────────────────────────────────────────────────────
    // BUILD REPORT
    //   - truck_no  comes from good_receipts_truck via b_cheque.good_receipts_truck_id
    //   - supplier  comes from suppliers table via b_cheque.supplier_id
    //   - maal      is child_cate_name from products_sub_cat_child
    //   - grouped by truck_no (vehicle), then by bilty_no inside each vehicle
    // ─────────────────────────────────────────────────────────────────────────
    private function buildReport(
        string  $dateFrom,
        string  $dateTo,
        ?string $supplierId,
        ?string $vehicleNo
    ): array {
        // ── Base query ────────────────────────────────────────────────────────
        $query = DB::table('b_cheque as bc')
            ->select(
                'bc.id_b_cheque',
                'bc.date',
                'bc.pb_no',
                'bc.bilty_no',
                'bc.good_receipts_truck_id',
                'bc.supplier_id',
                // supplier name from suppliers table
                'sup.supplier_name',
                // truck_no from good_receipts_truck
                'grt.truck_no',
                // detail columns
                'bcd.rent_recieve_amount',
                'bcd.labour_amount',
                'bcd.total_katta',
                'bcd.total_bori_mazdori',
                'bcd.labour_katta_amount',
                'bcd.market_fees_amount',
                'bcd.post_expense_amount',
                'bcd.miscellaneous_expense_amount',
                'bcd.cash_amount',
                'bcd.commission_rate',
                'bcd.commission_amount',
                'bcd.else_more_amount',
                'bcd.payment_details',
                'bcd.total_bori',
                'bcd.total_weight',
                'bcd.total_amount',
                'bcd.total_expanse_amount',
                'bcd.save_amount',
            )
            ->leftJoin('b_cheque_details as bcd',      'bcd.b_cheque_id',          '=', 'bc.id_b_cheque')
            ->leftJoin('suppliers as sup',              'sup.id_supplier',           '=', 'bc.supplier_id')
            ->leftJoin('good_receipts_truck as grt',    'grt.id_truck',              '=', 'bc.good_receipts_truck_id')
            ->where('bc.status', '1')
            ->whereBetween('bc.date', [$dateFrom, $dateTo]);

        if ($supplierId) {
            $query->where('bc.supplier_id', $supplierId);
        }

        if ($vehicleNo) {
            $query->where('grt.truck_no', 'like', "%{$vehicleNo}%");
        }

        $cheques = $query
            ->orderByRaw('grt.truck_no + 0')   // numeric sort on truck_no
            ->orderBy('bc.date')
            ->get();

        if ($cheques->isEmpty()) {
            return ['vehicles' => [], 'grandTotal' => $this->emptyTotals()];
        }

        // ── Load all items for these cheques ──────────────────────────────────
        $chequeIds = $cheques->pluck('id_b_cheque')->unique()->toArray();

        $items = DB::table('b_cheque_items as bci')
            ->select(
                'bci.b_cheque_id',
                'bci.marka',
                'bci.item',
                'bci.bori',
                'bci.weight',
                'bci.rate',
                'bci.amount',
                // maal = child_cate_name
                'psc.name      as child_cate_name',
                'psc.name_urdu as child_cate_urdu',
                // parent for reference
                'psp.name      as parent_cate_name',
                'psp.name_urdu as parent_cate_urdu',
                // main for reference
                'pcm.products_category_name      as main_cate_name',
                'pcm.products_category_name_urdu as main_cate_urdu',
            )
            ->leftJoin('products_sub_cat_child  as psc', 'psc.id_pro_sub_cat_child',  '=', 'bci.child_cate')
            ->leftJoin('products_sub_cat_parent as psp', 'psp.id_pro_sub_cat_parent', '=', 'bci.parent_cate')
            ->leftJoin('products_category_main  as pcm', 'pcm.id_pro_cate_main',      '=', 'bci.main_cate')
            ->whereIn('bci.b_cheque_id', $chequeIds)
            ->get()
            ->groupBy('b_cheque_id');

        // ── Build vehicle groups (keyed by truck_no) ──────────────────────────
        $vehicles   = [];
        $grandTotal = $this->emptyTotals();

        // Group cheques by truck_no
        $grouped = $cheques->groupBy(fn($c) => $c->truck_no ?? $c->pb_no ?? 'N/A');

        foreach ($grouped as $truckNo => $chequeGroup) {
            $vehicleTotals = $this->emptyTotals();
            $bilties       = [];

            foreach ($chequeGroup as $cheque) {
                $chequeItems = $items->get($cheque->id_b_cheque, collect())->toArray();

                $detail = [
                    'rent_recieve_amount'          => (float) ($cheque->rent_recieve_amount          ?? 0),
                    'labour_amount'                => (float) ($cheque->labour_amount                ?? 0),
                    'total_katta'                  => (int)   ($cheque->total_katta                  ?? 0),
                    'total_bori_mazdori'           => (int)   ($cheque->total_bori_mazdori           ?? 0),
                    'labour_katta_amount'          => (float) ($cheque->labour_katta_amount          ?? 0),
                    'market_fees_amount'           => (float) ($cheque->market_fees_amount           ?? 0),
                    'post_expense_amount'          => (float) ($cheque->post_expense_amount          ?? 0),
                    'miscellaneous_expense_amount' => (float) ($cheque->miscellaneous_expense_amount ?? 0),
                    'cash_amount'                  => (float) ($cheque->cash_amount                  ?? 0),
                    'commission_rate'              => (float) ($cheque->commission_rate              ?? 0),
                    'commission_amount'            => (float) ($cheque->commission_amount            ?? 0),
                    'else_more_amount'             => (float) ($cheque->else_more_amount             ?? 0),
                    'payment_details'              => $cheque->payment_details,
                    'total_bori'                   => (int)   ($cheque->total_bori                   ?? 0),
                    'total_weight'                 => (int)   ($cheque->total_weight                 ?? 0),
                    'total_amount'                 => (float) ($cheque->total_amount                 ?? 0),
                    'total_expanse_amount'         => (float) ($cheque->total_expanse_amount         ?? 0),
                    'save_amount'                  => (float) ($cheque->save_amount                  ?? 0),
                ];

                $bilty = [
                    'id'            => $cheque->id_b_cheque,
                    'date'          => $cheque->date,
                    'bilty_no'      => $cheque->bilty_no,
                    'supplier_name' => $cheque->supplier_name ?? $cheque->supplier_name,
                    'items'         => $chequeItems,
                    'detail'        => $detail,
                ];

                $this->addToTotals($vehicleTotals, $detail);
                $bilties[] = $bilty;
            }

            $this->addToTotals($grandTotal, $vehicleTotals);

            $vehicles[] = [
                'truck_no'      => $truckNo,
                'bilties'       => $bilties,
                'vehicleTotals' => $vehicleTotals,
                'pb_no' => $truckNo,
            ];

        }
// dd($vehicles);
        return [
            'vehicles'   => $vehicles,
            'grandTotal' => $grandTotal,
        ];
    }

    // ── Helpers ──────────────────────────────────────────────────────────────

    private function emptyTotals(): array
    {
        return [
            'rent_recieve_amount'          => 0.0,
            'labour_amount'                => 0.0,
            'labour_katta_amount'          => 0.0,
            'market_fees_amount'           => 0.0,
            'post_expense_amount'          => 0.0,
            'miscellaneous_expense_amount' => 0.0,
            'cash_amount'                  => 0.0,
            'commission_amount'            => 0.0,
            'else_more_amount'             => 0.0,
            'total_bori'                   => 0,
            'total_weight'                 => 0,
            'total_amount'                 => 0.0,
            'total_expanse_amount'         => 0.0,
            'save_amount'                  => 0.0,
        ];
    }

    private function addToTotals(array &$totals, array $detail): void
    {
        foreach ($totals as $key => &$val) {
            if (isset($detail[$key])) {
                $val += $detail[$key];
            }
        }
    }
}
