<?php

namespace App\Http\Controllers;

use App\Models\Branch;
use App\Models\CompanyProfile;
use App\Models\Customer;
use App\Models\Sale;
use App\Models\VatSetting;
use App\Models\VanSession;
use App\Models\Warehouse;
use App\Services\MoneyService;
use App\Services\InvoicePdfService;
use App\Services\SalesService;
use App\Services\ZatcaPhase1QrService;
use Illuminate\Http\Request;

class SalesController extends Controller
{
    public function __construct(private SalesService $sales, private InvoicePdfService $invoicePdf) {}

    public function index(Request $request)
    {
        $sales = Sale::with(['customer', 'warehouse'])
            ->when($request->filled('q'), fn ($q) => $q->where(fn ($sub) => $sub
                ->where('invoice_no', 'like', '%'.$request->q.'%')
                ->orWhereHas('customer', fn ($customer) => $customer->where('name_en', 'like', '%'.$request->q.'%')->orWhere('name_ar', 'like', '%'.$request->q.'%'))))
            ->when($request->filled('status'), fn ($q) => $q->where('status', $request->status))
            ->when($request->filled('date_from'), fn ($q) => $q->whereDate('invoice_date', '>=', $request->date_from))
            ->when($request->filled('date_to'), fn ($q) => $q->whereDate('invoice_date', '<=', $request->date_to))
            ->latest('invoice_date')->latest('id')->paginate(30)->withQueryString();
        return view('sales.index', compact('sales'));
    }

    public function create(Request $request)
    {
        $customers = Customer::where('status', 'active')->orderByRaw("CASE WHEN customer_code = 'CASH' THEN 0 ELSE 1 END")->orderBy('name_en')->limit(200)->get();
        if ($request->filled('customer_id') && !$customers->contains('id', $request->integer('customer_id'))) {
            $selectedCustomer = Customer::where('status', 'active')->find($request->integer('customer_id'));
            if ($selectedCustomer) $customers->prepend($selectedCustomer);
        }
        $warehouses = Warehouse::where('status', 'active')->when($request->van_session_id, fn ($q) => $q->where('type', 'van'))->orderBy('name_en')->get();
        $branches = Branch::where('status', 'active')->orderBy('name_en')->get();
        $vanSession = $request->van_session_id ? VanSession::where('status', 'open')->findOrFail($request->van_session_id) : null;
        return view('sales.create', compact('customers', 'warehouses', 'branches', 'vanSession'));
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'customer_id' => 'required|exists:customers,id', 'warehouse_id' => 'required|exists:warehouses,id',
            'branch_id' => 'nullable|exists:branches,id', 'van_session_id' => 'nullable|exists:van_sessions,id',
            'invoice_date' => 'required|date', 'invoice_type' => 'required|in:tax_invoice,simplified_tax_invoice,non_tax_invoice',
            'payment_type' => 'required|in:cash,credit,bank,card,transfer,mixed',
            'price_mode' => 'required|in:Exclusive VAT,Inclusive VAT', 'credit_days' => 'nullable|integer|min:0|max:3650',
            'po_number' => 'nullable|string|max:100', 'salesman' => 'nullable|string|max:100', 'notes' => 'nullable|string|max:2000',
            'credit_override' => 'nullable|boolean', 'action' => 'required|in:hold,finalize,finalize_print',
            'items' => 'required|array|min:1', 'items.*.product_id' => 'required|exists:products,id',
            'items.*.unit_id' => 'nullable|exists:units,id', 'items.*.quantity' => 'required|numeric|gt:0',
            'items.*.unit_price' => 'required|numeric|min:0', 'items.*.vat_rate' => 'required|numeric|min:0|max:100',
            'items.*.discount_type' => 'nullable|in:fixed,percentage', 'items.*.discount_value' => 'nullable|numeric|min:0',
            'payments' => 'nullable|array', 'payments.*.payment_method' => 'required_with:payments|in:cash,bank,card,transfer',
            'payments.*.amount' => 'required_with:payments|numeric|min:0', 'payments.*.reference' => 'nullable|string|max:100',
        ]);
        if (!empty($data['credit_override']) && !$request->user()->hasPermission('sales.credit_override')) {
            return back()->withInput()->with('error', 'You do not have permission to override customer credit controls.');
        }
        if ($data['action'] !== 'hold' && !$request->user()->hasPermission('sales.approve')) {
            abort(403, 'You do not have permission to finalize sales invoices.');
        }
        try {
            $sale = $this->sales->createDraft($data, $data['items'], $data['payments'] ?? []);
            if ($data['action'] !== 'hold') $sale = $this->sales->finalize($sale);
            if ($data['action'] === 'finalize_print') return redirect()->route('sales.print', $sale);
            return redirect()->route('sales.show', $sale)->with('success', $sale->status === 'draft' ? 'Invoice held successfully.' : 'Invoice finalized successfully.');
        } catch (\Throwable $e) {
            report($e); return back()->withInput()->with('error', $e->getMessage());
        }
    }

    public function show(Sale $sale)
    {
        $sale->load(['customer', 'warehouse', 'branch', 'items.product', 'payments', 'returns']);
        return view('sales.show', compact('sale'));
    }

    public function finalize(Sale $sale)
    {
        try { $this->sales->finalize($sale); return back()->with('success', 'Invoice finalized successfully.'); }
        catch (\Throwable $e) { report($e); return back()->with('error', $e->getMessage()); }
    }

    public function print(Sale $sale)
    {
        abort_unless($sale->status === 'finalized', 409, 'Only finalized invoices can be printed.');
        $sale->load(['customer', 'warehouse', 'branch', 'items.product', 'payments', 'createdBy']);
        $company = CompanyProfile::getProfile(); $vatSetting = VatSetting::getSettings();
        $qrSvg = $sale->invoice_type === 'non_tax_invoice' ? null : ZatcaPhase1QrService::generateQrSvg($sale->zatca_qr_tlv, 145);
        $amountInWordsEn = MoneyService::amountToWordsEn((float) $sale->grand_total, 'Saudi Riyal');
        $amountInWordsAr = MoneyService::amountToWordsAr((float) $sale->grand_total, 'ريال سعودي');
        return view('invoices.sale_a4', compact('sale', 'company', 'vatSetting', 'qrSvg', 'amountInWordsEn', 'amountInWordsAr'));
    }

    public function thermal(Sale $sale)
    {
        abort_unless($sale->status === 'finalized', 409, 'Only finalized invoices can be printed.');
        $sale->load(['customer', 'items', 'payments']); $company = CompanyProfile::getProfile();
        $qrSvg = $sale->invoice_type === 'non_tax_invoice' ? null : ZatcaPhase1QrService::generateQrSvg($sale->zatca_qr_tlv, 120);
        return view('invoices.sale_thermal', compact('sale', 'company', 'qrSvg'));
    }

    public function pdf(Sale $sale)
    {
        abort_unless($sale->status === 'finalized', 409, 'Only finalized invoices can be exported.');
        return $this->invoicePdf->sale($sale);
    }
}
