<?php

namespace App\Http\Controllers\Accounting;

use App\Http\Controllers\Controller;
use App\Models\Customer;
use App\Models\Product;
use App\Models\Quotation;
use App\Models\Invoice;
use App\Models\InvoiceItem;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Barryvdh\DomPDF\Facade\Pdf;

class QuotationController extends Controller
{
    public function index()
    {
        $quotations = Quotation::with('customer')->latest()->paginate(10);
        return view('accounting.quotations.index', compact('quotations'));
    }

    public function create()
    {
        $customers = Customer::orderBy('name')->get();
        $products = Product::orderBy('name')->get();
        $currencies = \App\Models\Currency::where('is_active', true)->get();
        $defaultCurrency = $currencies->where('is_base', true)->first() ?? $currencies->first();
        return view('accounting.quotations.create', compact('customers', 'products', 'currencies', 'defaultCurrency'));
    }

    public function store(Request $request)
    {
        $validated = $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'currency_id' => 'nullable|exists:currencies,id',
            'exchange_rate' => 'nullable|numeric|min:0',
            'date' => 'required|date',
            'expiry_date' => 'nullable|date|after_or_equal:date',
            'items' => 'required|array|min:1',
            'items.*.description' => 'required|string',
            'items.*.quantity' => 'required|numeric|min:0.01',
            'items.*.unit_price' => 'required|numeric|min:0',
            'discount_type' => 'nullable|in:fixed,percent',
            'discount_value' => 'nullable|numeric|min:0',
            'shipping_amount' => 'nullable|numeric|min:0',
            'extra_expenses_amount' => 'nullable|numeric|min:0',
            'extra_expenses_note' => 'nullable|string',
        ]);

        $currency_id = $validated['currency_id'] ?? null;
        $exchange_rate = $validated['exchange_rate'] ?? 1.0;

        // If no currency selected, use base
        if (!$currency_id) {
            $base = \App\Helpers\CurrencyHelper::getBaseCurrency();
            $currency_id = $base ? $base->id : null;
            $exchange_rate = 1.0;
        }

        DB::transaction(function () use ($request, $validated, $currency_id, $exchange_rate) {
            $quotation = Quotation::create([
                'customer_id' => $validated['customer_id'],
                'currency_id' => $currency_id,
                'exchange_rate' => $exchange_rate,
                'date' => $validated['date'],
                'expiry_date' => $request->expiry_date,
                'status' => 'draft',
                'notes' => $request->notes,
                'terms' => $request->terms,
                'discount_type' => $request->discount_type ?? 'fixed',
                'discount_value' => $request->discount_value ?? 0,
                'shipping_amount' => $request->shipping_amount ?? 0,
                'extra_expenses_amount' => $request->extra_expenses_amount ?? 0,
                'extra_expenses_note' => $request->extra_expenses_note,
            ]);

            $subtotal = 0;
            $taxTotal = 0;

            foreach ($request->items as $item) {
                $lineTotal = $item['quantity'] * $item['unit_price'];
                $subtotal += $lineTotal;

                $quotation->items()->create([
                    'product_id' => $item['product_id'] ?? null,
                    'description' => $item['description'],
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'],
                    'total' => $lineTotal,
                ]);
            }

            // Calculate Totals
            $discountAmount = 0;
            if ($quotation->discount_type === 'percent') {
                $discountAmount = ($subtotal * $quotation->discount_value) / 100;
            } else {
                $discountAmount = $quotation->discount_value;
            }

            $grandTotal = $subtotal - $discountAmount + $quotation->shipping_amount + $quotation->extra_expenses_amount;

            $quotation->update([
                'subtotal' => $subtotal,
                'grand_total' => $grandTotal,
            ]);
        });

        return redirect()->route('accounting.quotations.index')->with('success', 'Quotation created successfully.');
    }

    public function show(Quotation $quotation)
    {
        return view('accounting.quotations.show', compact('quotation'));
    }

    public function edit(Quotation $quotation)
    {
        if ($quotation->status === 'converted') {
            return redirect()->route('accounting.quotations.show', $quotation)
                ->with('error', 'Cannot edit a converted quotation.');
        }

        $customers = Customer::orderBy('name')->get();
        $products = Product::orderBy('name')->get();
        return view('accounting.quotations.edit', compact('quotation', 'customers', 'products'));
    }

    public function update(Request $request, Quotation $quotation)
    {
        if ($quotation->status === 'converted') {
            return back()->with('error', 'Cannot update a converted quotation.');
        }

        $validated = $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'date' => 'required|date',
            'items' => 'required|array|min:1',
            'discount_type' => 'nullable|in:fixed,percent',
            'discount_value' => 'nullable|numeric|min:0',
            'shipping_amount' => 'nullable|numeric|min:0',
            'extra_expenses_amount' => 'nullable|numeric|min:0',
            'extra_expenses_note' => 'nullable|string',
        ]);

        DB::transaction(function () use ($request, $quotation, $validated) {
            $quotation->update([
                'customer_id' => $validated['customer_id'],
                'date' => $validated['date'],
                'expiry_date' => $request->expiry_date,
                'notes' => $request->notes,
                'terms' => $request->terms,
                'discount_type' => $request->discount_type ?? 'fixed',
                'discount_value' => $request->discount_value ?? 0,
                'shipping_amount' => $request->shipping_amount ?? 0,
                'extra_expenses_amount' => $request->extra_expenses_amount ?? 0,
                'extra_expenses_note' => $request->extra_expenses_note,
            ]);

            $quotation->items()->delete();

            $subtotal = 0;

            foreach ($request->items as $item) {
                $lineTotal = $item['quantity'] * $item['unit_price'];
                $subtotal += $lineTotal;

                $quotation->items()->create([
                    'product_id' => $item['product_id'] ?? null,
                    'description' => $item['description'],
                    'quantity' => $item['quantity'],
                    'unit_price' => $item['unit_price'],
                    'total' => $lineTotal,
                ]);
            }

            // Calculate Totals
            $discountAmount = 0;
            if ($quotation->discount_type === 'percent') {
                $discountAmount = ($subtotal * $quotation->discount_value) / 100;
            } else {
                $discountAmount = $quotation->discount_value;
            }

            $grandTotal = $subtotal - $discountAmount + $quotation->shipping_amount + $quotation->extra_expenses_amount;

            $quotation->update([
                'subtotal' => $subtotal,
                'grand_total' => $grandTotal,
            ]);
        });

        return redirect()->route('accounting.quotations.show', $quotation)->with('success', 'Quotation updated successfully.');
    }

    public function convertToInvoice(Quotation $quotation)
    {
        if ($quotation->status === 'converted') {
            return back()->with('error', 'This quotation has already been converted.');
        }

        $invoice = DB::transaction(function () use ($quotation) {
            // Create Invoice
            $invoice = Invoice::create([
                'customer_id' => $quotation->customer_id,
                'invoice_date' => now(),
                'due_date' => now()->addDays(30),
                'status' => 'unpaid',
                'subtotal' => $quotation->subtotal,
                'tax_total' => $quotation->tax_total ?? 0, // Quotations don't strictly require tax logic in this simplified view, but usually they match.
                // Re-calculate or map discount/expenses?
                // The Invoice model expects `discount_amount`. The quotation logic used discount on total.
                // We should map them.
                'discount_type' => $quotation->discount_type,
                'discount_value' => $quotation->discount_value,
                'shipping_amount' => $quotation->shipping_amount,
                'extra_expenses_amount' => $quotation->extra_expenses_amount,
                'extra_expenses_note' => $quotation->extra_expenses_note,
                // Invoice "discount_amount" field needs to be calculated.
                'discount_amount' => ($quotation->discount_type == 'percent') ? ($quotation->subtotal * $quotation->discount_value / 100) : $quotation->discount_value,

                'total_amount' => $quotation->grand_total, // Rename check: In Invoice model it is `total`. `total_amount` might be wrong here?
                // Checking Invoice model... it has `total`. But `convertToInvoice` code had `total_amount`.
                // Let's check `Invoice` model in step 963. It has `total`. 
                // Wait, the previous code had `total_amount`. I need to be careful.
                // Line 173 said `'total_amount' => $quotation->grand_total`.
                // Checking Invoice migration (step 943: 0008_create_invoices_tables.php), let's assume `total` exists.
                // But looking at Invoice model (step 963), `fillable` has `total`.
                // So the existing code `total_amount` might be a bug or mapped via mutator?
                // I will use `total`. Re-reading step 963, line 29 is `total`.
                'total' => $quotation->grand_total,

                'notes' => $quotation->notes,
            ]);

            // Copy items
            foreach ($quotation->items as $item) {
                InvoiceItem::create([
                    'invoice_id' => $invoice->id,
                    'product_id' => $item->product_id,
                    'description' => $item->description,
                    'quantity' => $item->quantity,
                    'unit_price' => $item->unit_price,
                    'tax_rate' => $item->tax_rate,
                    'tax_amount' => $item->tax_amount,
                    'total_price' => $item->total,
                ]);
            }

            // Update Quotation status
            $quotation->update([
                'status' => 'converted',
                'converted_invoice_id' => $invoice->id,
            ]);

            return $invoice;
        });

        return redirect()->route('accounting.invoices.show', $invoice)->with('success', 'Quotation converted to invoice successfully.');
    }

    public function print(Quotation $quotation)
    {
        $settings = \App\Models\Setting::getGroup('general');
        return view('accounting.quotations.print', compact('quotation', 'settings'));
    }


    public function destroy(Quotation $quotation)
    {
        if ($quotation->status === 'converted') {
            return back()->with('error', 'Cannot delete a converted quotation.');
        }

        $quotation->items()->delete();
        $quotation->delete();

        return redirect()->route('accounting.quotations.index')
            ->with('success', 'Quotation deleted successfully.');
    }
}
