<?php

namespace App\Http\Controllers;

use App\Models\LCModule;
use App\Models\PurchaseDetails;
use App\Models\PurchaseMaster;
use App\Models\Supplier;
use App\Models\WorkOrderMerge;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Inertia\Inertia;

class LCModuleController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $lcData = LCModule::with(['supplier', 'cnf', 'workOrder', 'workOrderMerge'])->orderBy('created_at', 'desc')->get();
        $suppliers = Supplier::orderBy('id')->get();

        // If it's an AJAX request, return JSON
        if ($request->wantsJson()) {
            return response()->json([
                'lcData' => $lcData,
                'suppliers' => $suppliers,
            ]);
        }

        // Otherwise return Inertia view
        return Inertia::render('LCModule/LCModule', [
            'lcData' => $lcData,
            'suppliers' => $suppliers,
        ]);
    }

    /**
     * API for DataTable: paginated and searchable LC list.
     */
    public function view(Request $request)
    {
        $page = (int) $request->get('page', 1);
        $perPage = (int) $request->get('perPage', 10);
        $search = $request->get('search', '');

        $query = LCModule::with(['supplier', 'cnf', 'workOrder', 'workOrderMerge'])->orderBy('created_at', 'desc');

        if ($search !== '') {
            $query->where(function ($q) use ($search) {
                $q->where('lc_number', 'like', "%{$search}%")
                    ->orWhereHas('supplier', function ($sq) use ($search) {
                        $sq->where('name', 'like', "%{$search}%");
                    });
            });
        }

        $total = $query->count();
        $data = $query->skip(($page - 1) * $perPage)->take($perPage)->get();

        return response()->json([
            'data' => $data,
            'total' => $total,
        ]);
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create()
    {
        return Inertia::render('LCModule/LCModule');
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'lc_number' => 'required|string|max:255|unique:lc_modules',
            'lc_date' => 'required|date',
            'supplier_id' => 'required|exists:suppliers,id',
            'lc_payment_term' => 'nullable|string|max:255',
            'cnf_id' => 'nullable|exists:cnfs,id',
            'work_order_id' => 'nullable|exists:work_order_masters,id',
            'work_order_merge_id' => 'nullable|exists:work_order_merges,id',
            'current_step' => 'required',

            // Bank/LC Opening
            'lc_opening_amount' => 'nullable|numeric|min:0',
            'first_payment_amount' => 'nullable|numeric|min:0',

            // Documentation
            'documentation_cost' => 'nullable|numeric|min:0',

            // TT Payment
            'tt_payment_amount' => 'nullable|numeric|min:0',
            'bank_charge' => 'nullable|numeric|min:0',
            'foreign_bank_charge' => 'nullable|numeric|min:0',

            // Insurance
            'insurance_amount' => 'nullable|numeric|min:0',
            'insurance_vat' => 'nullable|numeric|min:0',
            'insurance_tax' => 'nullable|numeric|min:0',

            // Customs Duty & Tax
            'customs_duty' => 'nullable|numeric|min:0',
            'vat_amount' => 'nullable|numeric|min:0',
            'ait_amount' => 'nullable|numeric|min:0',
            'at_amount' => 'nullable|numeric|min:0',
            'port_charges' => 'nullable|numeric|min:0',

            // Transport
            'transport_cost' => 'nullable|numeric|min:0',
            'fuel_cost' => 'nullable|numeric|min:0',
            'toll_cost' => 'nullable|numeric|min:0',
            'loading_unloading_cost' => 'nullable|numeric|min:0',

            // Labour
            'port_labour_cost' => 'nullable|numeric|min:0',
            'warehouse_labour_cost' => 'nullable|numeric|min:0',

            // Total
            'total_amount' => 'required|numeric|min:0',
        ]);

        $validated['created_by'] = auth()->id();

        $lcModule = LCModule::create($validated);

        // Load supplier, cnf, workOrder and workOrderMerge relationships
        $lcModule->load(['supplier', 'cnf', 'workOrder', 'workOrderMerge']);

        return response()->json([
            'message' => 'LC record created successfully',
            'lcModule' => $lcModule,
        ], 201);
    }

    /**
     * Display the specified resource.
     */
    public function show(LCModule $lcModule)
    {
        return response()->json($lcModule);
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(LCModule $lcModule)
    {
        return Inertia::render('LCModule/LCModule', [
            'lcModule' => $lcModule,
        ]);
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, LCModule $lcModule)
    {
        $validated = $request->validate([
            'lc_number' => 'required|string|max:255|unique:lc_modules,lc_number,'.$lcModule->id,
            'lc_date' => 'required|date',
            'supplier_id' => 'required|exists:suppliers,id',
            'lc_payment_term' => 'nullable|string|max:255',
            'cnf_id' => 'nullable|exists:cnfs,id',
            'work_order_id' => 'nullable|exists:work_order_masters,id',
            'work_order_merge_id' => 'nullable|exists:work_order_merges,id',
            'current_step' => 'required',

            // Bank/LC Opening
            'lc_opening_amount' => 'nullable|numeric|min:0',
            'first_payment_amount' => 'nullable|numeric|min:0',

            // Documentation
            'documentation_cost' => 'nullable|numeric|min:0',

            // TT Payment
            'tt_payment_amount' => 'nullable|numeric|min:0',
            'bank_charge' => 'nullable|numeric|min:0',
            'foreign_bank_charge' => 'nullable|numeric|min:0',

            // Insurance
            'insurance_amount' => 'nullable|numeric|min:0',
            'insurance_vat' => 'nullable|numeric|min:0',
            'insurance_tax' => 'nullable|numeric|min:0',

            // Customs Duty & Tax
            'customs_duty' => 'nullable|numeric|min:0',
            'vat_amount' => 'nullable|numeric|min:0',
            'ait_amount' => 'nullable|numeric|min:0',
            'at_amount' => 'nullable|numeric|min:0',
            'port_charges' => 'nullable|numeric|min:0',

            // Transport
            'transport_cost' => 'nullable|numeric|min:0',
            'fuel_cost' => 'nullable|numeric|min:0',
            'toll_cost' => 'nullable|numeric|min:0',
            'loading_unloading_cost' => 'nullable|numeric|min:0',

            // Labour
            'port_labour_cost' => 'nullable|numeric|min:0',
            'warehouse_labour_cost' => 'nullable|numeric|min:0',

            // Total
            'total_amount' => 'required|numeric|min:0',
        ]);

        $validated['updated_by'] = auth()->id();

        $lcModule->update($validated);

        // Reload with supplier, cnf and workOrder relationships
        $lcModule->load(['supplier', 'cnf', 'workOrder']);

        return response()->json([
            'message' => 'LC record updated successfully',
            'lcModule' => $lcModule,
        ]);
    }

    /**
     * Remove the specified resource from storage.
     * Also deletes all purchases linked to this LC (purchase payment, details, then master).
     */
    public function destroy(LCModule $lcModule)
    {
        $lcId = $lcModule->id;

        $purchases = PurchaseMaster::withoutGlobalScope('typeScope')
            ->where('lc_module_id', $lcId)
            ->get();

        foreach ($purchases as $purchase) {
            $purchase->purchasePayment()->delete();
            $purchase->PurchaseDetalis()->delete();
            $purchase->delete();
        }

        $lcModule->delete();

        return response()->json([
            'message' => 'LC record deleted successfully',
        ]);
    }

    /**
     * Work order merge product list with merged qty and received qty (from purchases linked to this LC).
     * Load work order merge and compute merged product lines from source work orders.
     */
    public function workOrderPurchaseSummary(LCModule $lcModule)
    {
        if (! $lcModule->work_order_merge_id) {
            return response()->json([
                'work_order' => null,
                'details' => [],
            ]);
        }

        $workOrderMerge = \App\Models\WorkOrderMerge::find($lcModule->work_order_merge_id);

        if (! $workOrderMerge || empty($workOrderMerge->source_work_order_ids)) {
            return response()->json([
                'work_order' => null,
                'details' => [],
            ]);
        }

        // Load source work orders with quotation and their details
        $workOrders = \App\Models\WorkOrderMaster::withoutGlobalScope('typeScope')
            ->with(['quotation', 'workOrderDetails' => fn ($q) => $q->with('product', 'attribute')])
            ->whereIn('id', $workOrderMerge->source_work_order_ids)
            ->orderBy('id')
            ->get();

        if ($workOrders->isEmpty()) {
            return response()->json([
                'work_order' => null,
                'details' => [],
            ]);
        }

        // Group work orders by quotation_id (merge product lines per quotation)
        $byQuotation = [];
        foreach ($workOrders as $wo) {
            $qId = $wo->quotation_id ?? 0;
            $qNo = $wo->quotation?->quotation_number ?? ('WO #'.$wo->work_order_no);
            if (! isset($byQuotation[$qId])) {
                $byQuotation[$qId] = [
                    'quotation_id' => $wo->quotation_id,
                    'quotation_no' => $qNo,
                    'merged' => [],
                ];
            }
            foreach ($wo->workOrderDetails as $detail) {
                $key = $detail->product_id.'_'.$detail->attribute_id;
                $arr = &$byQuotation[$qId]['merged'];
                if (! isset($arr[$key])) {
                    $productName = $detail->product_name
                        ?? $detail->product?->name
                        ?? $detail->attribute?->product?->name
                        ?? '—';
                    $arr[$key] = [
                        'product_id' => $detail->product_id,
                        'attribute_id' => $detail->attribute_id,
                        'product_name' => $productName,
                        'quantity' => (float) $detail->quantity,
                        'price' => (float) ($detail->price ?? 0),
                        'total' => round((float) $detail->quantity * (float) ($detail->price ?? 0), 2),
                    ];
                } else {
                    $arr[$key]['quantity'] += (float) $detail->quantity;
                    $arr[$key]['total'] = round($arr[$key]['quantity'] * $arr[$key]['price'], 2);
                }
            }
        }

        // Build flat details list (quotation-wise order) with quotation info for frontend grouping
        $details = [];
        $index = 0;
        foreach ($byQuotation as $group) {
            foreach ($group['merged'] as $row) {
                $received = (float) PurchaseDetails::query()
                    ->whereHas('purchaseMaster', fn ($q) => $q->where('lc_module_id', $lcModule->id))
                    ->where('product_id', $row['product_id'])
                    ->where(function ($q) use ($row) {
                        if ($row['attribute_id'] !== null) {
                            $q->where('attribute_id', $row['attribute_id']);
                        } else {
                            $q->whereNull('attribute_id');
                        }
                    })
                    ->sum(DB::raw('CAST(quantity AS DECIMAL(20,2))'));

                $details[] = [
                    'id' => ++$index,
                    'product_id' => $row['product_id'],
                    'attribute_id' => $row['attribute_id'],
                    'product_name' => $row['product_name'],
                    'quantity' => $row['quantity'],
                    'price' => $row['price'],
                    'received_qty' => $received,
                    'quotation_id' => $group['quotation_id'],
                    'quotation_no' => $group['quotation_no'],
                ];
            }
        }

        // Existing purchase for this LC (so modal can update instead of create)
        $existingPurchase = PurchaseMaster::withoutGlobalScope('typeScope')
            ->where('lc_module_id', $lcModule->id)
            ->with('PurchaseDetalis')
            ->latest()
            ->first();

        $existingPurchasePayload = null;
        if ($existingPurchase) {
            $existingPurchasePayload = [
                'id' => $existingPurchase->id,
                'invoice_no' => $existingPurchase->invoice_no,
                'purchase_date' => $existingPurchase->purchase_date,
                'supplier_id' => $existingPurchase->supplier_id,
                'warehouse_id' => $existingPurchase->warehouse_id,
                'shop_warehouse_id' => $existingPurchase->shop_warehouse_id,
                'discount' => (float) ($existingPurchase->discount ?? 0),
                'total' => (float) ($existingPurchase->total ?? 0),
                'list' => $existingPurchase->PurchaseDetalis->map(function ($d) {
                    return [
                        'product_id' => $d->product_id,
                        'attribute_id' => $d->attribute_id,
                        'quantity' => (float) $d->quantity,
                        'unit_price' => (float) ($d->unit_price ?? 0),
                        'total' => (float) ($d->unit_price_total ?? $d->quantity * ($d->unit_price ?? 0)),
                    ];
                })->values()->all(),
            ];
        }

        return response()->json([
            'work_order' => [
                'id' => $workOrderMerge->id,
                'work_order_no' => $workOrderMerge->merge_work_order_no ?? ('mwo-'.sprintf('%04d', $workOrderMerge->id)),
            ],
            'details' => $details,
            'existing_purchase' => $existingPurchasePayload,
        ]);
    }
}
