<?php
namespace App\Http\Controllers\V1;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Schema;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use App\Models\CustomerVendor;
use App\Models\PurchaseOrder;
use App\Models\PurchaseOrderItem;
use App\Models\PurchaseOrderFile;
use App\Models\StockItem;
use App\Models\PurchaseQuotation;

class PurchaseOrderController extends Controller
{
    public function index(Request $request, $id = null)
    {
        $data = [];
        $filters = $request->get('filters', []);
        $page = $request->get('page', 1);
        $perPage = $request->get('per_page', 10);
        $query = PurchaseOrder::with(['items', 'files', 'vendor','quotation']);
        $columns = Schema::getColumnListing('purchase_orders');
        $data['columns'] = $columns;
        
        if (isset($filters['search'])) {
            $search = $filters['search'];
            unset($filters['search']);
            $query->where(function($q) use ($columns, $search) {
                foreach ($columns as $column) {
                    $q->orWhere($column, 'like', '%' . $search . '%');
                }
            });
        }
        
        if (count($filters) > 0) {
            foreach ($filters as $key => $value) {
                if (in_array($key, $columns)) {
                    $query->where($key, $value);
                }
            }
        }

        $purchaseQuotations = PurchaseQuotation::where('status', 'approved')
            ->with('items', 'items.stockItem', 'vendor')
            ->whereDoesntHave('purchaseOrder')
            ->get();
        $data['purchaseQuotations'] = $purchaseQuotations;
        
        $data['list'] = $query->paginate($perPage, $columns, null, $page);
        
        if ($id) {
            $purchaseOrder = PurchaseOrder::with(['items', 'files', 'vendor', 'quotation'])->find($id);
            $data['purchaseOrder'] = $purchaseOrder;
        } else {
            $nextPurchaseOrderNo = nextNumber('UEPL/PO', 'purchase_orders', 'purchase_order_no');
            $currentDate = date('Y-m-d');
            $vendors = CustomerVendor::where('company_role', 'Vendor')->get();
            $stockItems = StockItem::all();
            $quotations = PurchaseQuotation::where('status', 'approved')
                ->with('items', 'items.stockItem')
                ->whereDoesntHave('purchaseOrder')
                ->get();
            $data['nextPurchaseOrderNo'] = $nextPurchaseOrderNo;
            $data['currentDate'] = $currentDate;
            $data['vendors'] = $vendors;
            $data['stockItems'] = $stockItems;
            $data['quotations'] = $quotations;
        }
        //dd($data);
        return view('v1.purchaseorder.index', $data);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'purchase_order_no' => 'required|unique:purchase_orders,purchase_order_no',
            'purchase_order_date' => 'required|date',
            'vendor_id' => 'required|exists:customer_vendors,id',
            'vendor_ref_no' => 'nullable|string',
            'quotation_no' => 'nullable|string',
            'quotation_date' => 'nullable|date',
            'rfq_no' => 'nullable|string',
            'rfq_date' => 'nullable|date',
            'company_name' => 'required|string',
            'company_phone' => 'nullable|string',
            'company_email' => 'nullable|string',
            'company_gstn' => 'nullable|string',
            'company_address' => 'nullable|string',
            'bill_address' => 'nullable|string',
            'ship_address' => 'nullable|string',
            'subtotal' => 'nullable|numeric',
            'sgst_amount' => 'nullable|numeric',
            'cgst_amount' => 'nullable|numeric',
            'igst_amount' => 'nullable|numeric',
            'additional_charges' => 'nullable|numeric',
            'tds_amount' => 'nullable|numeric',
            'net_payable_amount' => 'nullable|numeric',
            'grand_total' => 'nullable|numeric',
            'inr_in_words' => 'nullable|string',
            'description' => 'nullable|string',
            'delivery_terms' => 'nullable|string',
            'note' => 'nullable|string',

            'items' => 'required|array|min:1',
            'items.*.stock_item_id' => 'required|exists:stock_items,id',
            'items.*.stock_item_name' => 'nullable|string',
            'items.*.quantity' => 'required|numeric',
            'items.*.uom' => 'nullable|string',
            'items.*.unit_rate' => 'required|numeric',
            'items.*.tds' => 'nullable|numeric',
            'items.*.discount' => 'nullable|numeric',
            'items.*.value' => 'nullable|numeric',
            'items.*.sgst' => 'nullable|numeric',
            'items.*.cgst' => 'nullable|numeric',
            'items.*.igst' => 'nullable|numeric',
            'items.*.amount' => 'nullable|numeric',

            'purchaseOrderFiles' => 'nullable|array',
            'purchaseOrderFiles.*' => 'file|mimes:pdf,jpg,jpeg,png|max:2048',
        ]);

        DB::transaction(function () use ($data, $request) {
            // Prepare purchase order data (exclude items and files)
            $poData = $data;
            unset($poData['items'], $poData['purchaseOrderFiles']);

            $purchaseOrder = PurchaseOrder::create($poData);

            foreach ($data['items'] as $item) {
                $itemData = $item;
                $itemData['purchase_order_id'] = $purchaseOrder->id;
                PurchaseOrderItem::create($itemData);
            }

            if ($request->hasFile('purchaseOrderFiles')) {
                foreach ($request->file('purchaseOrderFiles') as $file) {
                    $path = $file->store('purchase_orders', 'public');
                    PurchaseOrderFile::create([
                        'purchase_order_id' => $purchaseOrder->id,
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_size' => $file->getSize(),
                    ]);
                }
            }
        });

        return redirect()->route('superadmin.purchaseorder.index')
            ->with('success', 'Purchase Order created successfully!');
    }

    public function update(Request $request, $id)
    {
        $purchaseOrder = PurchaseOrder::findOrFail($id);

        $data = $request->validate([
            'purchase_order_no' => 'required|exists:purchase_orders,purchase_order_no',
            'purchase_order_date' => 'required|date',
            'vendor_id' => 'required|exists:customer_vendors,id',
            'vendor_ref_no' => 'nullable|string',
            'quotation_no' => 'nullable|string',
            'quotation_date' => 'nullable|date',
            'rfq_no' => 'nullable|string',
            'rfq_date' => 'nullable|date',
            'company_name' => 'required|string',
            'company_phone' => 'nullable|string',
            'company_email' => 'nullable|string',
            'company_gstn' => 'nullable|string',
            'company_address' => 'nullable|string',
            'bill_address' => 'nullable|string',
            'ship_address' => 'nullable|string',
            'subtotal' => 'nullable|numeric',
            'sgst_amount' => 'nullable|numeric',
            'cgst_amount' => 'nullable|numeric',
            'igst_amount' => 'nullable|numeric',
            'additional_charges' => 'nullable|numeric',
            'tds_amount' => 'nullable|numeric',
            'net_payable_amount' => 'nullable|numeric',
            'grand_total' => 'nullable|numeric',
            'inr_in_words' => 'nullable|string',
            'description' => 'nullable|string',
            'delivery_terms' => 'nullable|string',
            'note' => 'nullable|string',

            'items' => 'required|array|min:1',
            'items.*.stock_item_id' => 'required|exists:stock_items,id',
            'items.*.stock_item_name' => 'nullable|string',
            'items.*.quantity' => 'required|numeric',
            'items.*.uom' => 'nullable|string',
            'items.*.unit_rate' => 'required|numeric',
            'items.*.tds' => 'nullable|numeric',
            'items.*.discount' => 'nullable|numeric',
            'items.*.value' => 'nullable|numeric',
            'items.*.sgst' => 'nullable|numeric',
            'items.*.cgst' => 'nullable|numeric',
            'items.*.igst' => 'nullable|numeric',
            'items.*.amount' => 'nullable|numeric',

            'purchaseOrderFiles' => 'nullable|array',
            'purchaseOrderFiles.*' => 'file|mimes:pdf,jpg,jpeg,png|max:2048',
        ]);

        DB::transaction(function () use ($data, $request, $purchaseOrder) {
            // Update purchase order data (exclude items and files)
            $poData = $data;
            unset($poData['items'], $poData['purchaseOrderFiles']);

            $purchaseOrder->update($poData);
            $existingItemIds = $purchaseOrder->items()->pluck('stock_item_id')->toArray();
            $incomingItemIds = array_column($data['items'], 'stock_item_id');

            // Delete items that are no longer in the incoming data
            $itemsToDelete = array_diff($existingItemIds, $incomingItemIds);
            if (!empty($itemsToDelete)) {
                $purchaseOrder->items()->whereIn('stock_item_id', $itemsToDelete)->delete();
            }

            // Update existing items or create new ones
            foreach ($data['items'] as $item) {
                $itemData = $item;
                $itemData['purchase_order_id'] = $purchaseOrder->id;
                
                PurchaseOrderItem::updateOrCreate(
                    [
                        'purchase_order_id' => $purchaseOrder->id,
                        'stock_item_id' => $item['stock_item_id']
                    ],
                    $itemData
                );
            }

            // Handle new file uploads
            if ($request->hasFile('purchaseOrderFiles')) {
                foreach ($request->file('purchaseOrderFiles') as $file) {
                    $path = $file->store('purchase_orders', 'public');
                    PurchaseOrderFile::create([
                        'purchase_order_id' => $purchaseOrder->id,
                        'file_path' => $path,
                        'file_name' => $file->getClientOriginalName(),
                        'file_size' => $file->getSize(),
                    ]);
                }
            }
        });

        return redirect()->route('superadmin.purchaseorder.index')
            ->with('success', 'Purchase Order updated successfully!');
    }

    public function destroy(Request $request, $id)
    {
        try {
            $purchaseOrder = PurchaseOrder::findOrFail($id);
            $purchaseOrder->items()->delete();
            $purchaseOrder->files()->delete();
            $purchaseOrder->delete();

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

    public function create()
    {
        $data = [];
        $data['nextPurchaseOrderNo'] = nextNumber('UEPL/PO', 'purchase_orders', 'purchase_order_no');
        $data['currentDate'] = date('Y-m-d');
        $data['vendors'] = CustomerVendor::where('company_role', 'Vendor')->get();
        $data['purchaseQuotations'] = PurchaseQuotation::where('status', 'approved')
            ->with('items', 'items.stockItem', 'vendor')
            ->whereDoesntHave('purchaseOrder')
            ->get();
        $stockItems = StockItem::all();
        $data['stockItems'] = $stockItems;
        $columns = Schema::getColumnListing('purchase_orders');
        $data['columns'] = $columns;
        return view('v1.purchaseorder.create', $data);
    }

    public function edit($id)
    {
        $purchaseOrder = PurchaseOrder::with(['items', 'files', 'vendor', 'quotation'])->findOrFail($id);
        $data = [];
        $data['purchaseOrder'] = $purchaseOrder;
        $data['nextPurchaseOrderNo'] = nextNumber('UEPL/PO', 'purchase_orders', 'purchase_order_no');
        $data['currentDate'] = date('Y-m-d');
        $data['vendors'] = CustomerVendor::where('company_role', 'Vendor')->get();
        $data['purchaseQuotations'] = PurchaseQuotation::where('status', 'approved')
            ->with('items', 'items.stockItem', 'vendor')
            ->whereDoesntHave('purchaseOrder')
            ->get();
        $stockItems = StockItem::all();
        $data['stockItems'] = $stockItems;
        $columns = Schema::getColumnListing('purchase_orders');
        $data['columns'] = $columns;
        return view('v1.purchaseorder.edit', $data);
    }

    // Show a single purchase order
    public function show($id)
    { 
        $purchaseOrder = PurchaseOrder::with(['items.stockItem', 'files', 'vendor'])->findOrFail($id);
        return view('v1.purchaseorder.show', compact('purchaseOrder'));
    }

    // Print a purchase order
    public function print($id)
    {
        $purchaseOrder = PurchaseOrder::with(['items.stockItem'])->findOrFail($id);
        return view('v1.purchaseorder.print', compact('purchaseOrder'));
    }

    // Approve a purchase order
    public function approve($id)
    {
        $purchaseOrder = PurchaseOrder::findOrFail($id);
        $purchaseOrder->status = 'approved';
        $purchaseOrder->save();
        return redirect()->route('superadmin.purchaseorder.index')->with('success', 'Purchase Order approved successfully!');
    }

    // Reject a purchase order
    public function reject($id)
    {
        $purchaseOrder = PurchaseOrder::findOrFail($id);
        $purchaseOrder->status = 'rejected';
        $purchaseOrder->save();
        return redirect()->route('superadmin.purchaseorder.index')->with('success', 'Purchase Order rejected successfully!');
    }

    // Delete file
    public function deleteFile($id)
    {
        $file = PurchaseOrderFile::findOrFail($id);

        if (Storage::disk('public')->exists($file->file_path)) {
            Storage::disk('public')->delete($file->file_path);
        }

        $file->delete();

        return redirect()->back()->with('success', 'File deleted successfully.');
    }

    // Get quotation details for auto-fill
    public function getQuotationDetails($quotationNo)
    {
        $quotation = PurchaseQuotation::with(['items.stockItem', 'vendor'])
            ->where('quotation_no', $quotationNo)
            ->first();

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

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

    // Get item row for AJAX
    public function getItemRow(Request $request)
    {
        $index = $request->get('index', 0);
        $stockItems = StockItem::all();
        return view('v1.purchaseorder.item-row', compact('index', 'stockItems'));
    }
} 