<?php

class PurchaseController extends Controller
{
    public function index(): void
    {
        Auth::requirePermission('purchasing', 'view');

        $status = $this->input('status', 'ALL');
        $search = trim($this->input('search', ''));
        $dateFrom = $this->input('date_from', '');
        $dateTo = $this->input('date_to', '');

        $poModel = new PurchaseOrder();
        $supplierModel = new Supplier();
        $materialModel = new RawMaterial();
        $db = Database::getConnection();

        $summary = $poModel->summaryStats($dateFrom, $dateTo);
        $paymentRate = (float) $summary['total_purchased'] > 0
            ? round(((float) $summary['total_paid'] / (float) $summary['total_purchased']) * 100, 1)
            : 0;

        $this->view('purchasing.index', [
            'pageTitle'    => 'Purchasing',
            'orders'       => $poModel->listFiltered($status, $search, $dateFrom, $dateTo),
            'summary'      => $summary,
            'paymentRate'  => $paymentRate,
            'activeStatus' => $status,
            'search'       => $search,
            'dateFrom'     => $dateFrom,
            'dateTo'       => $dateTo,
            'suppliers'    => $supplierModel->all('supplier_name ASC'),
            'materials'    => $materialModel->allOrdered(),
            'financeAccounts' => $db->query("SELECT * FROM finance_accounts WHERE is_active = 1")->fetchAll(),
            'csrf'         => $this->csrfField(),
        ]);
    }

    public function store(): void
    {
        Auth::requirePermission('purchasing', 'add');
        $this->verifyCsrf();

        $supplierId = (int) $this->input('supplier_id', 0);
        $cartJson = $this->input('cart_json', '[]');
        $cart = json_decode($cartJson, true);
        $expectedDate = $this->input('expected_date', '') ?: null;
        $notes = trim($this->input('notes', ''));

        if ($supplierId <= 0 || !is_array($cart) || count($cart) === 0) {
            $this->redirect('purchasing');
            return;
        }

        $items = [];
        foreach ($cart as $line) {
            $materialId = (int) ($line['raw_material_id'] ?? 0);
            $qty = (float) ($line['quantity'] ?? 0);
            $cost = (float) ($line['unit_cost'] ?? 0);
            if ($materialId > 0 && $qty > 0) {
                $items[] = ['raw_material_id' => $materialId, 'quantity' => $qty, 'unit_cost' => $cost];
            }
        }
        if (count($items) === 0) {
            $this->redirect('purchasing');
            return;
        }

        $poModel = new PurchaseOrder();
        $poId = $poModel->createWithItems($supplierId, $items, $expectedDate, $notes, Auth::id());

        AuditLogger::log(Auth::id(), 'PO_CREATE', 'purchasing', "Created purchase order #{$poId}");
        $this->redirect('purchasing/show?id=' . $poId);
    }

    public function show(): void
    {
        Auth::requirePermission('purchasing', 'view');
        $id = (int) $this->input('id');

        $poModel = new PurchaseOrder();
        $po = $poModel->findWithItems($id);
        if (!$po) {
            $this->redirect('purchasing');
            return;
        }

        $db = Database::getConnection();
        $this->view('purchasing.show', [
            'pageTitle'       => $po['po_number'],
            'po'              => $po,
            'financeAccounts' => $db->query("SELECT * FROM finance_accounts WHERE is_active = 1")->fetchAll(),
            'csrf'            => $this->csrfField(),
        ]);
    }

    public function receive(): void
    {
        Auth::requirePermission('purchasing', 'edit');
        $this->verifyCsrf();

        $poId = (int) $this->input('id');
        $receipts = $this->input('receive', []); // [item_id => qty]

        $poModel = new PurchaseOrder();
        $poModel->receiveItems($poId, is_array($receipts) ? $receipts : [], Auth::id());

        AuditLogger::log(Auth::id(), 'PO_RECEIVE', 'purchasing', "Received goods for PO #{$poId}");
        $this->redirect('purchasing/show?id=' . $poId);
    }

    public function pay(): void
    {
        Auth::requirePermission('purchasing', 'edit');
        $this->verifyCsrf();

        $poId = (int) $this->input('id');
        $amount = (float) $this->input('amount', 0);
        $accountId = (int) $this->input('finance_account_id', 0);
        $notes = trim($this->input('notes', ''));

        if ($amount > 0 && $accountId > 0) {
            $poModel = new PurchaseOrder();
            $poModel->recordPayment($poId, $amount, $accountId, $notes, Auth::id());
            AuditLogger::log(Auth::id(), 'PO_PAYMENT', 'purchasing', "Paid " . formatMoney($amount) . " for PO #{$poId}");
        }
        $this->redirect('purchasing/show?id=' . $poId);
    }

    public function cancel(): void
    {
        Auth::requirePermission('purchasing', 'edit');
        $this->verifyCsrf();

        $poId = (int) $this->input('id');
        (new PurchaseOrder())->cancel($poId);
        AuditLogger::log(Auth::id(), 'PO_CANCEL', 'purchasing', "Cancelled PO #{$poId}");
        $this->redirect('purchasing/show?id=' . $poId);
    }
}
