<?php
class CustomerReceiptsController extends Controller
{
    public function indexAction($page = 1)
    {
        $page    = max(1, (int)$page);
        $perPage = defined('ROWS_PER_PAGE') ? ROWS_PER_PAGE : 20;

        $filters = [
            'q'           => trim((string)($_GET['q']           ?? '')),
            'status'      => trim((string)($_GET['status']      ?? '')),
            'customer_id' => (int)($_GET['customer_id']         ?? 0),
            'from_date'   => trim((string)($_GET['from_date']   ?? '')),
            'to_date'     => trim((string)($_GET['to_date']     ?? '')),
            'method'      => trim((string)($_GET['method']      ?? '')),
        ];

        $m      = new CustomerReceipts();
        $result = $m->listPaginated($page, $perPage, $filters);

        $qs = http_build_query(array_filter($filters, fn($v) => $v !== '' && $v !== 0));
        $pg = Pagination::paginate($result['total'], $perPage, $page, PROOT . 'CustomerReceipts/index/');
        $pgHtml = $pg['html'];
        if ($qs && $pgHtml) $pgHtml = preg_replace('~href=\'([^\']+)\'~', "href='$1?" . htmlspecialchars($qs) . "'", $pgHtml);

        $this->view->setLayout($this->roleLayout());
        $this->view->render('CustomerReceipts/index', [
            'page_title' => 'Customer Receipts',
            'rows'       => $result['rows'],
            'total'      => $result['total'],
            'page'       => $page,
            'filters'    => $filters,
            'pg_html'    => $pgHtml,
        ]);
    }

    public function recordAction()
    {
        $customerId = (int)($_GET['customer_id'] ?? 0);
        $db = new DB();

        // Customers with open (issued/partially_paid) invoices
        $customers = $db->mySelect(
            "SELECT c.c0d, TRIM(CONCAT(c.fname, ' ', c.lname)) AS customer_name,
                    COUNT(i.c0d) AS open_count, SUM(i.total_amount - i.amount_paid) AS outstanding
               FROM customers c
               JOIN customer_invoices i ON i.customer_id = c.c0d
              WHERE i.deleted = 0 AND i.status IN ('issued','partially_paid')
           GROUP BY c.c0d
           ORDER BY outstanding DESC",
            []
        ) ?: [];

        $openInvoices = [];
        if ($customerId > 0) {
            $openInvoices = $db->mySelect(
                "SELECT c0d AS invoice_id, invoice_no, invoice_date, due_date, total_amount, amount_paid,
                        (total_amount - amount_paid) AS outstanding, currency
                   FROM customer_invoices
                  WHERE customer_id = :cid AND deleted = 0 AND status IN ('issued','partially_paid')
               ORDER BY invoice_date ASC",
                [':cid' => $customerId]
            ) ?: [];
        }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('CustomerReceipts/record', [
            'page_title'    => 'Record Receipt',
            'customers'     => $customers,
            'customer_id'   => $customerId,
            'open_invoices' => $openInvoices,
        ]);
    }

    public function saveAction()
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('CustomerReceipts/record'); return; }

        $allocations = [];
        $ids  = $_POST['alloc_invoice_id']   ?? [];
        $amts = $_POST['alloc_amount']       ?? [];
        if (is_array($ids)) {
            foreach ($ids as $k => $iid) {
                $amt = (float)($amts[$k] ?? 0);
                if ((int)$iid > 0 && $amt > 0) $allocations[] = ['invoice_id' => (int)$iid, 'amount' => $amt];
            }
        }

        $r = (new CustomerReceipts())->record([
            'customer_id'    => (int)($_POST['customer_id'] ?? 0),
            'amount'         => $_POST['amount']         ?? 0,
            'receipt_date'   => $_POST['receipt_date']   ?? '',
            'payment_method' => $_POST['payment_method'] ?? 'bank_transfer',
            'reference'      => $_POST['reference']      ?? '',
            'notes'          => $_POST['notes']          ?? '',
            'allocations'    => $allocations,
        ], $this->currentUserId(), $_SESSION['full_name'] ?? '');

        if (!$r['ok']) {
            $_SESSION['flash_tenant_msg']  = $r['msg'];
            $_SESSION['flash_tenant_type'] = 'danger';
            Router::redirect('CustomerReceipts/record?customer_id=' . (int)($_POST['customer_id'] ?? 0)); return;
        }
        $_SESSION['flash_tenant_msg']  = $r['msg'];
        $_SESSION['flash_tenant_type'] = 'success';
        Router::redirect('CustomerReceipts/view/' . $r['id']);
    }

    public function viewAction($id = 0)
    {
        $m = new CustomerReceipts();
        $rcpt = $m->byId((int)$id);
        if (!$rcpt) { $this->notFound('Receipt'); return; }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('CustomerReceipts/view', [
            'page_title'  => $rcpt['receipt_no'] . ' · Receipt',
            'rcpt'        => $rcpt,
            'allocations' => $m->allocationsFor((int)$id),
        ]);
    }

    public function voidAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('CustomerReceipts/view/' . (int)$id); return; }
        $reason = trim((string)($_POST['reason'] ?? ''));
        if ($reason === '') { $_SESSION['flash_tenant_msg'] = 'Reason required.'; $_SESSION['flash_tenant_type'] = 'danger'; Router::redirect('CustomerReceipts/view/' . (int)$id); return; }
        $r = (new CustomerReceipts())->voidReceipt((int)$id, $reason, $this->currentUserId(), $_SESSION['full_name'] ?? '');
        $_SESSION['flash_tenant_msg']  = $r['msg'];
        $_SESSION['flash_tenant_type'] = $r['ok'] ? 'success' : 'danger';
        Router::redirect('CustomerReceipts/view/' . (int)$id);
    }

    private function notFound(string $what): void
    {
        $this->view->setLayout($this->roleLayout());
        $this->view->render('generals/fb_page', [
            'page_title' => 'Not found',
            'fb_msg'     => '<div class="alert alert-danger">' . htmlspecialchars($what) . ' not found.</div>',
        ]);
    }
}
