<?php

namespace App\Http\Controllers;

use App\Models\Account;
use App\Models\AccountTransaction;
use App\Models\DeliveryReceipt;
use App\Models\DeliveryReceiptItem;
use App\Models\FactoryInvoice;
use App\Models\FactoryInvoiceItem;
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\View\View;
use Illuminate\Support\Facades\DB;
use Yajra\DataTables\Facades\DataTables;

class DeliveryReceiptController extends Controller
{
    /**
     * Display a listing of delivery receipts
     */
    public function index(): View
    {
        return view('delivery-receipts.index');
    }

    /**
     * Get data for DataTables
     */
    public function getData(Request $request)
    {
        $query = DeliveryReceipt::with(['invoice.customer', 'deliveryMan']);

        // Apply filters
        if ($request->filled('status') && $request->status !== 'all') {
            $query->where('status', $request->status);
        }

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

        if ($request->filled('date_from') && $request->filled('date_to')) {
            $query->whereBetween('delivery_date', [$request->date_from, $request->date_to]);
        }

        return DataTables::of($query)
            ->addColumn('invoice_number', function ($receipt) {
                return $receipt->invoice->invoice_number ?? 'N/A';
            })
            ->addColumn('customer_name', function ($receipt) {
                return $receipt->invoice->customer->name ?? 'N/A';
            })
            ->addColumn('delivery_man', function ($receipt) {
                return $receipt->deliveryMan->name ?? 'N/A';
            })
            ->addColumn('status_badge', function ($receipt) {
                $badges = [
                    'draft' => '<span class="badge bg-secondary">Draft</span>',
                    'submitted' => '<span class="badge bg-warning">Submitted</span>',
                    'processed' => '<span class="badge bg-success">Processed</span>',
                ];
                return $badges[$receipt->status] ?? '<span class="badge bg-secondary">' . ucfirst($receipt->status) . '</span>';
            })
            ->addColumn('actions', function ($receipt) {
                $actions = '<a href="' . route('delivery-receipts.show', $receipt) . '" class="btn btn-sm btn-info">View</a>';

                if (!$receipt->isProcessed()) {
                    $actions .= ' <a href="' . route('delivery-receipts.edit', $receipt) . '" class="btn btn-sm btn-warning">Edit</a>';

                    if ($receipt->isSubmitted()) {
                        $actions .= ' <button onclick="processReceipt(' . $receipt->id . ')" class="btn btn-sm btn-success">Process</button>';
                    }
                }

                return $actions;
            })
            ->rawColumns(['status_badge', 'actions'])
            ->make(true);
    }

    /**
     * Show the form for creating a new delivery receipt
     */
    public function create(Request $request): View
    {
        // Get picked invoices that don't have delivery receipts yet
        $invoices = FactoryInvoice::where('status', 'picked')
                                 ->whereDoesntHave('deliveryReceipts')
                                 ->with(['customer', 'items.item'])
                                 ->orderBy('created_at', 'desc')
                                 ->get();

        // Get delivery men (employees)
        $deliveryMen = Account::where('model_type', 'contact')
                             ->whereHas('contact', function($q) {
                                 $q->where('type', 'employee');
                             })
                             ->where('is_active', true)
                             ->orderBy('name')
                             ->get();

        return view('delivery-receipts.create', compact('invoices', 'deliveryMen'));
    }

    /**
     * Store a newly created delivery receipt
     */
    public function store(Request $request): RedirectResponse
    {
        $request->validate([
            'factory_invoice_id' => 'required|exists:factory_invoices,id',
            'delivered_by' => 'required|exists:accounts,id',
            'delivery_date' => 'required|date',
            'items' => 'required|array',
            'items.*.factory_invoice_item_id' => 'required|exists:factory_invoice_items,id',
            'items.*.delivered_quantity' => 'required|numeric|min:0',
            'items.*.delivered_unit_price' => 'required|numeric|min:0',
            'notes' => 'nullable|string|max:1000',
        ]);

        DB::transaction(function () use ($request) {
            // Create delivery receipt
            $receipt = DeliveryReceipt::create([
                'factory_invoice_id' => $request->factory_invoice_id,
                'delivered_by' => $request->delivered_by,
                'delivery_date' => $request->delivery_date,
                'notes' => $request->notes,
                'status' => 'draft',
            ]);

            // Create delivery receipt items and update factory invoice items
            foreach ($request->items as $itemData) {
                $invoiceItem = FactoryInvoiceItem::find($itemData['factory_invoice_item_id']);

                // Calculate delivered total
                $deliveredTotal = $itemData['delivered_quantity'] * $itemData['delivered_unit_price'];

                // Update factory invoice item with delivered quantities
                $invoiceItem->update([
                    'delivered_quantity' => $itemData['delivered_quantity'],
                    'delivered_unit_price' => $itemData['delivered_unit_price'],
                    'delivered_total' => $deliveredTotal,
                ]);

                // Create delivery receipt item
                DeliveryReceiptItem::create([
                    'delivery_receipt_id' => $receipt->id,
                    'factory_invoice_item_id' => $itemData['factory_invoice_item_id'],
                    'delivered_quantity' => $itemData['delivered_quantity'],
                    'delivered_unit_price' => $itemData['delivered_unit_price'],
                    'delivered_total' => $deliveredTotal,
                    'notes' => $itemData['notes'] ?? null,
                ]);
            }
        });

        return redirect()->route('delivery-receipts.index')->with('success', 'Delivery receipt created successfully');
    }

    /**
     * Display the specified delivery receipt
     */
    public function show(DeliveryReceipt $receipt): View
    {
        $receipt->load(['invoice.customer', 'deliveryMan', 'items.invoiceItem.item']);

        return view('delivery-receipts.show', compact('receipt'));
    }

    /**
     * Show the form for editing the delivery receipt
     */
    public function edit(DeliveryReceipt $receipt): View
    {
        if ($receipt->isProcessed()) {
            abort(403, 'Cannot edit processed delivery receipt');
        }

        $receipt->load(['invoice.customer', 'deliveryMan', 'items.invoiceItem.item']);

        // Get delivery men (employees)
        $deliveryMen = Account::where('model_type', 'contact')
                             ->whereHas('contact', function($q) {
                                 $q->where('type', 'employee');
                             })
                             ->where('is_active', true)
                             ->orderBy('name')
                             ->get();

        return view('delivery-receipts.edit', compact('receipt', 'deliveryMen'));
    }

    /**
     * Update the specified delivery receipt
     */
    public function update(Request $request, DeliveryReceipt $receipt): RedirectResponse
    {
        if ($receipt->isProcessed()) {
            abort(403, 'Cannot edit processed delivery receipt');
        }

        $request->validate([
            'delivered_by' => 'required|exists:accounts,id',
            'delivery_date' => 'required|date',
            'items' => 'required|array',
            'items.*.id' => 'required|exists:delivery_receipt_items,id',
            'items.*.delivered_quantity' => 'required|numeric|min:0',
            'items.*.delivered_unit_price' => 'required|numeric|min:0',
            'notes' => 'nullable|string|max:1000',
        ]);

        DB::transaction(function () use ($request, $receipt) {
            // Update delivery receipt
            $receipt->update([
                'delivered_by' => $request->delivered_by,
                'delivery_date' => $request->delivery_date,
                'notes' => $request->notes,
            ]);

            // Update delivery receipt items and factory invoice items
            foreach ($request->items as $itemData) {
                $receiptItem = DeliveryReceiptItem::find($itemData['id']);
                $invoiceItem = $receiptItem->invoiceItem;

                // Calculate delivered total
                $deliveredTotal = $itemData['delivered_quantity'] * $itemData['delivered_unit_price'];

                // Update delivery receipt item
                $receiptItem->update([
                    'delivered_quantity' => $itemData['delivered_quantity'],
                    'delivered_unit_price' => $itemData['delivered_unit_price'],
                    'delivered_total' => $deliveredTotal,
                    'notes' => $itemData['notes'] ?? null,
                ]);

                // Update factory invoice item
                $invoiceItem->update([
                    'delivered_quantity' => $itemData['delivered_quantity'],
                    'delivered_unit_price' => $itemData['delivered_unit_price'],
                    'delivered_total' => $deliveredTotal,
                ]);
            }
        });

        return redirect()->route('delivery-receipts.show', $receipt)->with('success', 'Delivery receipt updated successfully');
    }

    /**
     * Submit delivery receipt for processing
     */
    public function submit(DeliveryReceipt $receipt): RedirectResponse
    {
        if (!$receipt->isDraft()) {
            abort(403, 'Receipt is not in draft status');
        }

        $receipt->update(['status' => 'submitted']);

        return redirect()->back()->with('success', 'Delivery receipt submitted for processing');
    }

    /**
     * Process delivery receipt and create transactions
     */
    public function process(DeliveryReceipt $receipt)
    {
        if (!$receipt->isSubmitted()) {
            return response()->json(['error' => 'Receipt must be submitted before processing'], 400);
        }

        DB::transaction(function () use ($receipt) {
            // Calculate actual delivered amounts
            $deliveredTotal = $receipt->items->sum('delivered_total');

            // Update factory invoice with delivered amounts and status
            $invoice = $receipt->invoice;
            $invoice->update([
                'total_delivered_amount' => $deliveredTotal,
                'status' => 'completed',
                'delivered_at' => $receipt->delivery_date,
                'delivered_by' => $receipt->delivered_by,
            ]);

            // Create customer transaction (accounts receivable)
            AccountTransaction::create([
                'account_id' => $invoice->customer_account_id,
                'chart_of_account_id' => $invoice->customer->chart_of_account_id,
                'amount' => $deliveredTotal,
                'transaction_type' => 'debit', // Customer owes us
                'reference_id' => $invoice->id,
                'reference_type' => 'factory_invoice',
                'remarks' => 'Factory sales invoice - ' . $invoice->invoice_number,
            ]);

            // Update delivery receipt status
            $receipt->update(['status' => 'processed']);
        });

        return response()->json(['success' => true, 'message' => 'Delivery receipt processed successfully']);
    }

    /**
     * Get invoice items for a specific invoice (AJAX)
     */
    public function getInvoiceItems(FactoryInvoice $invoice)
    {
        $items = $invoice->items()->with('item')->get();

        return response()->json([
            'items' => $items->map(function ($item) {
                return [
                    'id' => $item->id,
                    'item_name' => $item->item->name ?? 'N/A',
                    'ordered_quantity' => $item->ordered_quantity,
                    'picked_quantity' => $item->picked_quantity,
                    'ordered_unit_price' => $item->ordered_unit_price,
                    'ordered_total' => $item->ordered_total,
                ];
            })
        ]);
    }
}
