<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use App\Models\PurchaseOrder;
use App\Models\PurchaseOrderItem;
use App\Models\CustomerVendor;
use App\Models\Quotation;

class PurchaseController extends Controller
{
    // Show the PO create form
    public function purchasePage()
    {
        Log::info("admin accessed Purchase Order Form");
        return view('admin.purchase.purchaseorder');
    }
    public function print($id)
    {
        $po =PurchaseOrder::with(['items', 'vendor'])->findOrFail($id);
        return view('admin.purchase.print', compact('po'));
    }
    // List all purchase orders
    public function purchaseDetails()
    {
        Log::info("admin accessed Purchase Details Page");
        $purchaseOrders = PurchaseOrder::with('vendor')->orderBy('id', 'desc')->get();
        return view('admin.purchase.purchasedetails', compact('purchaseOrders'));
    }

    // Show PO details (view page)
    public function show($id)
    {
        $po = PurchaseOrder::with(['items', 'vendor'])->findOrFail($id);
        return view('admin.purchase.show', compact('po'));
    }

    // Get PO details as JSON (for AJAX/edit)
    public function getPurchaseOrderById($id)
    {
        $order = PurchaseOrder::with(['items', 'vendor'])->findOrFail($id);
        return response()->json($order);
    }

    // Get all vendor quotations (for dropdown)
    public function getQuotations()
    {
        $quotations = Quotation::with('customer')
            ->whereHas('customer', function ($q) {
                $q->where('company_role', '!=', 'Customer');
            })
            ->orderBy('id', 'desc')
            ->get(['id', 'quotation_no']);
        return response()->json($quotations);
    }

    // Get single vendor quotation by id (for autofill)
    public function getQuotationById($id)
    {
        $quotation = Quotation::with('customer', 'rfq')
            ->whereHas('customer', function ($q) {
                $q->where('company_role', '!=', 'Customer');
            })
            ->find($id);

        if (!$quotation) {
            return response()->json(['error' => 'Quotation not found or not for a Vendor'], 404);
        }

        return response()->json($quotation);
    }

    // Generate the next PO ID
    public function generatePOId()
    {
        try {
            $lastPo = PurchaseOrder::orderByDesc('id')->first();
            if ($lastPo && isset($lastPo->purchase_order_no)) {
                $lastId = intval(preg_replace('/[^0-9]/', '', substr($lastPo->purchase_order_no, -4)));
            } else {
                $lastId = 0;
            }
            $newId = str_pad($lastId + 1, 4, '0', STR_PAD_LEFT);
            $poId = "UEPL/PO/{$newId}";
            return response()->json(['so_id' => $poId]);
        } catch (\Exception $e) {
            return response()->json(['so_id' => 'UEPL/PO/0001']);
        }
    }

    // Store new PO
    public function store(Request $request)
    {
        Log::info('[PurchaseOrder] Store called');
        try {
            Log::info('[PurchaseOrder] Incoming request data:', $request->all());

            $validated = $request->validate([
                'soNo1' => 'required|unique:purchase_orders,purchase_order_no',
                'soDate' => 'required|date',
                'companyId' => 'required|string',
                'grandTotal' => 'required|numeric'
            ]);
            Log::info('[PurchaseOrder] Validation passed', $validated);

            DB::beginTransaction();

            $purchaseOrder = PurchaseOrder::create([
                'purchase_order_no'   => $request->input('soNo1'),
                'purchase_order_date' => $request->input('soDate'),
                'grn_no'              => $request->input('grnNo1') ?? null,
                'quotation_no'        => $request->input('quotationNo2') ?? null,
                'quotation_date'      => $request->input('quotationDate') ?? null,
                'customer_ref_no'     => $request->input('custRefSoNo') ?? null,
                'company_name'        => $request->input('companyId'),
                'company_address'     => $request->input('soCompanyAddress'),
                'company_gstn'        => $request->input('soCompanyGSTN'),
                'company_phone'       => $request->input('soCompanyPhone'),
                'company_email'       => $request->input('soCompanyEmail'),
                'bill_address'        => $request->input('billAddress') ?? null,
                'ship_address'        => $request->input('shipAddress') ?? null,
                'product_type'        => $request->input('productType'),
                'inr_in_words'        => $request->input('GT_in_letters'),
                'subtotal'            => $request->input('totalAmount'),
                'sgst_amount'         => $request->input('sgstA'),
                'cgst_amount'         => $request->input('cgstA'),
                'igst_amount'         => $request->input('IgstA'),
                'round_up'            => $request->input('roundUp'),
                'grand_total'         => $request->input('grandTotal'),
                'rfq_no'              => $request->input('rfqNo') ?? null,
                'rfq_date'            => $request->input('rfqDate') ?? null,
                'part_no'             => $request->input('partNo') ?? null,
                'project_material_no' => $request->input('projectMaterialNo') ?? null,
                'drawing_no'          => $request->input('drawingId') ?? null,
                'drawing_rev'         => $request->input('drawingRevision') ?? null,
                'description'         => $request->input('projectDescription') ?? null,
            ]);
            Log::info('[PurchaseOrder] PurchaseOrder created', ['id' => $purchaseOrder->id]);

            $items = $request->input('tableProducts');
            Log::info('[PurchaseOrder] tableProducts received:', ['tableProducts' => $items]);
            if (!is_array($items)) {
                throw new \Exception("Invalid items format received");
            }

            foreach ($items as $item) {
                PurchaseOrderItem::create([
                    'purchase_order_id'    => $purchaseOrder->id,
                    'sl_no'                => $item['slNo'] ?? null,
                    'material_code'        => $item['materialCode'] ?? null,
                    'hsn_code'             => $item['hsnCode'] ?? null,
                    'material_description' => $item['description'] ?? null,
                    'additional_details'   => $item['additionalDetails'] ?? null,
                    'required_by_date'     => $item['reqByDate'] ?? null,
                    'quantity'             => $item['quantity'] ?? 0,
                    'uom'                  => $item['uom'] ?? null,
                    'unit_rate'            => $item['unitRate'] ?? 0,
                    'discount'             => $item['discount'] ?? 0,
                    'value'                => $item['value'] ?? 0,
                    'sgst'                 => $item['sgst'] ?? 0,
                    'cgst'                 => $item['cgst'] ?? 0,
                    'igst'                 => $item['igst'] ?? 0,
                    'amount'               => $item['amount'] ?? 0,
                ]);
            }
            Log::info('[PurchaseOrder] PurchaseOrderItems created');

            DB::commit();

            Log::info('[PurchaseOrder] Purchase order saved successfully', ['id' => $purchaseOrder->id]);
            return response()->json([
                'message' => 'Purchase Order saved successfully!',
                'id' => $purchaseOrder->id
            ], 201);
        } catch (\Illuminate\Validation\ValidationException $e) {
            DB::rollBack();
            Log::error('[PurchaseOrder] Validation failed', [
                'errors' => $e->validator->getMessageBag(),
                'trace' => $e->getTraceAsString(),
            ]);
            return response()->json(['error' => 'Validation failed', 'details' => $e->validator->getMessageBag()], 422);
        } catch (\Exception $e) {
            DB::rollBack();
            Log::error('[PurchaseOrder] Exception occurred', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
                'request_data' => $request->all()
            ]);
            return response()->json(['error' => 'Server error occurred', 'message' => $e->getMessage()], 500);
        }
    }

    // Edit purchase order (returns view)
    public function edit($id)
    {
        $po = PurchaseOrder::with('items', 'vendor')->findOrFail($id);
        $vendors = CustomerVendor::where('company_role', 'Vendor')->select('id', 'company')->get();
        $editOrderId = $id;
        return view('admin.purchase.edit', compact('po', 'vendors', 'editOrderId'));
    }

    // Update existing purchase order
    public function update(Request $request, $id)
    {
        Log::info("[PurchaseOrder] Starting Purchase Order Update...");
        try {
            Log::debug("Incoming Request Data:", $request->all());
    
            $validated = $request->validate([
                'soNo1' => 'required|unique:purchase_orders,purchase_order_no,' . $id,
                'soDate' => 'required|date',
                'companyId' => 'required|string',
                'grandTotal' => 'required|numeric'
            ]);
    
            DB::beginTransaction();
    
            $purchaseOrder = PurchaseOrder::findOrFail($id);
            $purchaseOrder->update([
                'purchase_order_no'   => $request->input('soNo1'),
                'purchase_order_date' => $request->input('soDate'),
                'grn_no'              => $request->input('grnNo1') ?? null,
                'quotation_no'        => $request->input('quotationId') ?? null,
                'quotation_date'      => $request->input('quotationDate') ?? null,
                'customer_ref_no'     => $request->input('custRefSoNo') ?? null,
                'company_name'        => $request->input('companyId'),
                'company_address'     => $request->input('soCompanyAddress'),
                'company_gstn'        => $request->input('soCompanyGSTN'),
                'company_phone'       => $request->input('soCompanyPhone'),
                'company_email'       => $request->input('soCompanyEmail'),
                'bill_address'        => $request->input('billAddress') ?? null,
                'ship_address'        => $request->input('shipAddress') ?? null,
                'product_type'        => $request->input('productType'),
                'inr_in_words'        => $request->input('GT_in_letters'),
                'subtotal'            => $request->input('totalAmount'),
                'sgst_amount'         => $request->input('sgstA'),
                'cgst_amount'         => $request->input('cgstA'),
                'igst_amount'         => $request->input('IgstA'),
                'round_up'            => $request->input('roundUp'),
                'grand_total'         => $request->input('grandTotal'),
                'rfq_no'              => $request->input('rfqNo') ?? null,
                'rfq_date'            => $request->input('rfqDate') ?? null,
                'part_no'             => $request->input('partNo') ?? null,
                'project_material_no' => $request->input('projectMaterialNo') ?? null,
                'drawing_no'          => $request->input('drawingId') ?? null,
                'drawing_rev'         => $request->input('drawingRevision') ?? null,
                'description'         => $request->input('projectDescription') ?? null,
                // 'quotation_id'     => $request->input('quotationId') ?? null, // Only if your table supports it
            ]);
    
            // Remove existing items and save new
            $purchaseOrder->items()->delete();
            $items = $request->input('tableProducts');
            if (is_string($items)) {
                $items = json_decode($items, true);
            }
            if (!is_array($items)) {
                $items = [];
            }
            foreach ($items as $item) {
                PurchaseOrderItem::create([
                    'purchase_order_id'    => $purchaseOrder->id,
                    'sl_no'                => $item['slNo'] ?? null,
                    'material_code'        => $item['materialCode'] ?? null,
                    'hsn_code'             => $item['hsnCode'] ?? null,
                    'material_description' => $item['description'] ?? null,
                    'additional_details'   => $item['additionalDetails'] ?? null,
                    'required_by_date'     => $item['reqByDate'] ?? null,
                    'quantity'             => is_numeric($item['quantity']) ? $item['quantity'] : 0,
                    'uom'                  => $item['uom'] ?? null,
                    'unit_rate'            => is_numeric($item['unitRate']) ? $item['unitRate'] : 0,
                    'discount'             => is_numeric($item['discount']) ? $item['discount'] : 0,
                    'value'                => is_numeric($item['value']) ? $item['value'] : 0,
                    'sgst'                 => is_numeric($item['sgst']) ? $item['sgst'] : 0,
                    'cgst'                 => is_numeric($item['cgst']) ? $item['cgst'] : 0,
                    'igst'                 => is_numeric($item['igst']) ? $item['igst'] : 0,
                    'amount'               => is_numeric($item['amount']) ? $item['amount'] : 0,
                ]);
            }
    
            DB::commit();
    
            return response()->json([
                'message' => 'Purchase Order updated successfully!',
                'id' => $purchaseOrder->id
            ], 200);
        } catch (\Illuminate\Validation\ValidationException $e) {
            DB::rollBack();
            return response()->json(['error' => 'Validation failed', 'details' => $e->validator->getMessageBag()], 422);
        } catch (\Exception $e) {
            DB::rollBack();
            return response()->json(['error' => 'Server error occurred', 'message' => $e->getMessage()], 500);
        }
    }


    // Delete purchase order
    public function destroy($id)
    {
        try {
            $order = PurchaseOrder::findOrFail($id);
            $order->items()->delete();
            $order->delete();

            return response()->json(['message' => 'Purchase Order deleted successfully']);
        } catch (\Exception $e) {
            return response()->json(['error' => 'Failed to delete order'], 500);
        }
    }
}
