<?php
class CustomerInvoicesController 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']     ?? '')),
            'overdue'     => (int)($_GET['overdue']             ?? 0),
        ];

        $m      = new CustomerInvoices();
        $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 . 'CustomerInvoices/index/');
        $pgHtml = $pg['html'];
        if ($qs && $pgHtml) $pgHtml = preg_replace('~href=\'([^\']+)\'~', "href='$1?" . htmlspecialchars($qs) . "'", $pgHtml);

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

    public function billTripsAction()
    {
        $m = new CustomerInvoices();
        $customerId = (int)($_GET['customer_id'] ?? 0);
        $customers  = $m->customersWithUnbilled();
        $trips      = $customerId > 0 ? $m->unbilledTripsForCustomer($customerId) : [];

        $this->view->setLayout($this->roleLayout());
        $this->view->render('CustomerInvoices/billTrips', [
            'page_title' => 'Bill Trips',
            'customers'  => $customers,
            'customer_id'=> $customerId,
            'trips'      => $trips,
        ]);
    }

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

        $customerId = (int)($_POST['customer_id'] ?? 0);
        $tripIds    = array_map('intval', $_POST['trip_ids'] ?? []);
        $opts = [
            'invoice_date'    => trim((string)($_POST['invoice_date']    ?? '')),
            'payment_terms'   => trim((string)($_POST['payment_terms']   ?? 'Net 30')),
            'due_date'        => trim((string)($_POST['due_date']        ?? '')) ?: null,
            'currency'        => trim((string)($_POST['currency']        ?? 'TZS')),
            'vat_rate'        => (float)($_POST['vat_rate']              ?? CustomerInvoices::VAT_RATE_DEFAULT),
            'revenue_account' => trim((string)($_POST['revenue_account'] ?? '4010')),
            'notes'           => trim((string)($_POST['notes']           ?? '')),
            'footer_note'     => trim((string)($_POST['footer_note']     ?? '')),
            'billing_address' => trim((string)($_POST['billing_address'] ?? '')),
        ];

        $r = (new CustomerInvoices())->createFromTrips($customerId, $tripIds, $opts, $this->currentUserId());
        if (!$r['ok']) {
            $_SESSION['flash_tenant_msg']  = $r['msg'];
            $_SESSION['flash_tenant_type'] = 'danger';
            Router::redirect('CustomerInvoices/billTrips?customer_id=' . $customerId); return;
        }
        $_SESSION['flash_tenant_msg']  = $r['msg'] . ' Review then issue.';
        $_SESSION['flash_tenant_type'] = 'success';
        Router::redirect('CustomerInvoices/view/' . $r['id']);
    }

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

        $this->view->setLayout($this->roleLayout());
        $this->view->render('CustomerInvoices/view', [
            'page_title' => $inv['invoice_no'] . ' · Invoice',
            'inv'        => $inv,
            'lines'      => $m->linesFor((int)$id),
            'receipts'   => $m->receiptsFor((int)$id),
        ]);
    }

    public function issueAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('CustomerInvoices/view/' . (int)$id); return; }
        $r = (new CustomerInvoices())->issue((int)$id, $this->currentUserId(), $_SESSION['full_name'] ?? '');
        $_SESSION['flash_tenant_msg']  = $r['msg'];
        $_SESSION['flash_tenant_type'] = $r['ok'] ? 'success' : 'danger';
        Router::redirect('CustomerInvoices/view/' . (int)$id);
    }

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

    public function deleteAction($id = 0)
    {
        $this->verifyCsrf();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') { Router::redirect('CustomerInvoices/view/' . (int)$id); return; }
        $r = (new CustomerInvoices())->softDelete((int)$id, $this->currentUserId());
        $_SESSION['flash_tenant_msg']  = $r['msg'] ?? 'Deleted.';
        $_SESSION['flash_tenant_type'] = $r['ok'] ? 'success' : 'danger';
        Router::redirect($r['ok'] ? 'CustomerInvoices' : 'CustomerInvoices/view/' . (int)$id);
    }

    public function printableAction($id = 0)
    {
        $m = new CustomerInvoices();
        $inv = $m->byId((int)$id);
        if (!$inv) { $this->notFound('Invoice'); return; }
        // Print layout — bare shell, print-friendly CSS in the view
        $this->view->setLayout('l_auth');
        $this->view->render('CustomerInvoices/print', [
            'page_title' => $inv['invoice_no'] . ' · Print',
            'inv'        => $inv,
            'lines'      => $m->linesFor((int)$id),
        ]);
    }

    /**
     * FPDF-rendered invoice with the Pacific logo + brand palette.
     * Streams to browser as an inline PDF by default; add ?dl=1 to force
     * a download attachment.
     */
    public function pdfAction($id = 0)
    {
        $m = new CustomerInvoices();
        $inv = $m->byId((int)$id);
        if (!$inv) { $this->notFound('Invoice'); return; }

        if (!class_exists('FPDF')) require_once ROOT . '/core/FPDF.php';

        $pdf = new PacificInvoicePdf();
        $pdf->setInvoice($inv, $m->linesFor((int)$id));
        $pdf->render();

        // Ensure no stray output pollutes the PDF stream
        if (ob_get_length()) ob_clean();

        $filename = preg_replace('/[^A-Za-z0-9_-]/', '_', $inv['invoice_no']) . '.pdf';
        $mode     = !empty($_GET['dl']) ? 'D' : 'I';   // I = inline preview, D = force download
        $pdf->Output($mode, $filename);
        exit();
    }

    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>',
        ]);
    }
}
