<?php
class SalesController extends Controller
{
    public function indexAction()
    {
        $m         = new Sales();
        $projectId = (int)($_GET['project_id'] ?? 0);
        $rows      = $m->list((string)($_GET['status'] ?? ''), $projectId);

        $projName = '';
        if ($projectId > 0) {
            $db = new DB();
            $r = $db->mySelect("SELECT project_no, project_name FROM c_projects WHERE c0d = :id", [':id' => $projectId]);
            if (!empty($r)) $projName = $r[0]['project_no'] . ' · ' . $r[0]['project_name'];
        }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Sales/index', [
            'page_title'           => 'Customer Invoices',
            'rows'                 => $rows,
            'status'               => (string)($_GET['status'] ?? ''),
            'filter_project'       => $projectId,
            'filter_project_label' => $projName,
        ]);
    }

    /**
     * Slice 8Z-x · Overdue invoices queue — actionable list for Accountant + FM daily use.
     * URL: /Sales/overdue?min_days=0  (0 = include upcoming due; 1+ = only past due)
     */
    public function overdueAction()
    {
        $minDays = isset($_GET['min_days']) ? (int)$_GET['min_days'] : 1;
        $m       = new Sales();
        $rows    = $m->overdueList($minDays);
        $buckets = $m->agedBuckets();
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Sales/overdue', [
            'page_title' => 'Overdue Invoices',
            'rows'       => $rows,
            'buckets'    => $buckets,
            'min_days'   => $minDays,
        ]);
    }

    public function draftAction()
    {
        $db = new DB();
        $projects = $db->mySelect(
            "SELECT p.c0d, p.project_no, p.project_name, p.project_type,
                    p.project_customer, p.project_customer_id, p.currency
               FROM c_projects p
              WHERE p.deleted = 0
                AND (p.crm_status = 'APPROVED' OR p.migrated_flag = 1)
              ORDER BY p.c0d DESC",
            []
        ) ?: [];

        // Optional prefill from a Client PO -------------------------------
        $prefill  = [];
        $cpo      = null;
        $cpoItems = [];
        if (!empty($_GET['client_po_id'])) {
            $gm  = new GoodsClientPos();
            $cpo = $gm->byId((int)$_GET['client_po_id']);
            if ($cpo) {
                $cpoItems = $gm->itemsFor((int)$cpo['c0d']);
                $prefill  = [
                    'client_po_id'  => (int)$cpo['c0d'],
                    'client_po_no'  => (string)$cpo['client_po_no'],
                    'project_id'    => (int)$cpo['project_id'],
                    'customer_id'   => (int)$cpo['customer_id'],
                    'currency'      => (string)$cpo['currency'],
                    'vat_rate'      => (float)$cpo['vat_rate'],
                    'source_module' => (string)$cpo['source_module'],
                    'narrative'     => 'Invoice against Client PO ' . $cpo['client_po_no']
                                     . ($cpo['customer_po_ref'] ? ' (their ref: ' . $cpo['customer_po_ref'] . ')' : ''),
                ];
            }
        }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Sales/draft', [
            'page_title' => 'Draft Invoice' . ($cpo ? ' · from ' . $cpo['client_po_no'] : ''),
            'projects'   => $projects,
            'fb_msg'     => '',
            'form'       => $prefill,
            'cpo'        => $cpo,
            'cpo_items'  => $cpoItems,
        ]);
    }

    public function saveAction()
    {
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
            Router::redirect('Sales/draft');
            return;
        }
        // Rebuild items[] from parallel arrays
        $descs = $_POST['item_description'] ?? [];
        $qtys  = $_POST['item_qty']         ?? [];
        $units = $_POST['item_unit']        ?? [];
        $ups   = $_POST['item_unit_price']  ?? [];
        $items = [];
        for ($i = 0; $i < count($descs); $i++) {
            if (trim((string)$descs[$i]) === '') continue;
            $items[] = [
                'description' => (string)$descs[$i],
                'qty'         => (float)($qtys[$i]  ?? 0),
                'unit'        => (string)($units[$i] ?? ''),
                'unit_price'  => (float)($ups[$i]   ?? 0),
            ];
        }

        $d = [
            'project_id'   => (int)($_POST['project_id']  ?? 0),
            'customer_id'  => (int)($_POST['customer_id'] ?? 0),
            'client_po_id' => (int)($_POST['client_po_id'] ?? 0),
            'invoice_date' => (string)($_POST['invoice_date'] ?? date('Y-m-d')),
            'due_date'     => (string)($_POST['due_date'] ?? ''),
            'currency'     => (string)($_POST['currency'] ?? 'TZS'),
            'vat_rate'     => (float) ($_POST['vat_rate'] ?? 18),
            'source_module'=> (string)($_POST['source_module'] ?? 'goods'),
            'narrative'    => (string)($_POST['narrative'] ?? ''),
            'items'        => $items,
        ];

        $m = new Sales();
        $r = $m->draft($d, $this->currentUserId(), $_SESSION['full_name'] ?? '');
        if (!$r['ok']) {
            $db = new DB();
            $projects = $db->mySelect(
                "SELECT p.c0d, p.project_no, p.project_name, p.project_type, p.project_customer, p.project_customer_id, p.currency
                   FROM c_projects p WHERE p.deleted = 0 AND (p.crm_status = 'APPROVED' OR p.migrated_flag = 1)
                  ORDER BY p.c0d DESC",
                []
            ) ?: [];
            $this->view->setLayout($this->roleLayout());
            $this->view->render('Sales/draft', [
                'page_title' => 'Draft Invoice',
                'projects'   => $projects,
                'fb_msg'     => '<div class="alert alert-danger">' . htmlspecialchars($r['msg']) . '</div>',
                'form'       => $_POST,
            ]);
            return;
        }
        Router::redirect('Sales/view/' . (int)$r['id']);
    }

    public function viewAction($id = 0)
    {
        $m = new Sales();
        $s = $m->byId((int)$id);
        if (!$s) {
            $this->view->setLayout($this->roleLayout());
            $this->view->render('generals/fb_page', ['fb_msg' => '<div class="alert alert-danger">Invoice not found.</div>']);
            return;
        }
        $items    = $m->itemsFor((int)$id);
        $ac       = new ApprovalChain();
        $approval = ((int)$s['approval_id'] > 0) ? $ac->approvalById((int)$s['approval_id']) : [];
        $steps    = !empty($approval) ? $ac->stepsForChain((int)$approval['chain_id']) : [];
        $history  = !empty($approval) ? $ac->historyFor((int)$s['approval_id']) : [];

        $je = [];
        $jls = [];
        if ((int)$s['journal_entry_id'] > 0) {
            $jp  = new JournalPosting();
            $je  = $jp->byId((int)$s['journal_entry_id']);
            $jls = $jp->linesForJe((int)$s['journal_entry_id']);
        }

        $rm       = new Receipts();
        $receipts = $rm->forSale((int)$id);
        $group    = strtolower($this->currentUserGroup());
        $balance  = round((float)$s['total'] - (float)$s['amount_paid'], 2);
        $canReceive = in_array($group, ['accountant','finance manager','administrator'], true)
                      && $s['invoice_workflow_status'] === 'ISSUED'
                      && $balance > 0.01;

        $cpo = [];
        if ((int)$s['client_po_id'] > 0) {
            $gm  = new GoodsClientPos();
            $cpo = $gm->byId((int)$s['client_po_id']);
        }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Sales/view', [
            'page_title'  => ($s['sale_no'] ?: $s['invoice_ref']) . ' · ' . $s['customer_name'],
            's'           => $s,
            'items'       => $items,
            'approval'    => $approval,
            'steps'       => $steps,
            'history'     => $history,
            'je'          => $je,
            'je_lines'    => $jls,
            'receipts'    => $receipts,
            'balance'     => $balance,
            'can_receive' => $canReceive,
            'cpo'         => $cpo,
        ]);
    }

    /** AJAX: submit a DRAFT invoice into GOODS_CUSTOMER_INVOICE chain. */
    public function submitAjAction()
    {
        $sid = (int)($_POST['sale_id'] ?? 0);
        if ($sid <= 0) { $this->jsonResponse(['ok' => false, 'msg' => 'sale_id required']); return; }

        $m = new Sales();
        $s = $m->byId($sid);
        if (!$s) { $this->jsonResponse(['ok' => false, 'msg' => 'Invoice not found']); return; }
        if ($s['invoice_workflow_status'] !== 'DRAFT') {
            $this->jsonResponse(['ok' => false, 'msg' => 'Invoice is not in DRAFT.']); return;
        }

        $ac  = new ApprovalChain();
        $ref = ($s['invoice_ref'] ?: $s['sale_no']) . ' · ' . ($s['customer_name'] ?: '(customer)')
             . ' · ' . $s['currency'] . ' ' . number_format((float)$s['total']);
        $res = $ac->submit([
            'chain_key'    => 'GOODS_CUSTOMER_INVOICE',
            'entity_type'  => 'sales',
            'entity_id'    => $sid,
            'ref_label'    => $ref,
            'return_url'   => 'Sales/view/' . $sid,
            'user_id'      => $this->currentUserId(),
            'user_name'    => $_SESSION['full_name'] ?? '',
            'user_group'   => $_SESSION['user_group_name'] ?? '',
            'comment'      => 'Invoice submitted for review.',
        ]);
        if ($res['ok']) {
            $m->markSubmitted($sid, (int)$res['approval_id']);
        }
        $this->jsonResponse($res);
    }
}
