<?php
/**
 * CreditNotesController — Slice 8Z-y
 *
 * Endpoints:
 *   /CreditNotes                       GET  — list
 *   /CreditNotes/view/{id}             GET  — detail
 *   /CreditNotes/draft/{sale_id}       GET  — draft form for a specific sale
 *   /CreditNotes/saveDraftAj           POST — persist draft
 *   /CreditNotes/issueAj               POST — flip to ISSUED (with optional EFD refs)
 *   /CreditNotes/cancelAj              POST — cancel a DRAFT (not ISSUED)
 */
class CreditNotesController extends Controller
{
    public function indexAction()
    {
        $rows = (new CreditNotes())->list((string)($_GET['status'] ?? ''));
        $this->view->setLayout($this->roleLayout());
        $this->view->render('CreditNotes/index', [
            'page_title' => 'Credit Notes',
            'rows'       => $rows,
            'status'     => (string)($_GET['status'] ?? ''),
        ]);
    }

    public function viewAction($id = 0)
    {
        $id = (int)$id;
        $m  = new CreditNotes();
        $cn = $m->find($id);
        if (empty($cn)) { $this->fb('Credit note not found.'); return; }
        $lines = $m->linesFor($id);
        $group = strtolower(trim($this->currentUserGroup()));
        $canIssue  = in_array($group, ['accountant','administrator'], true) && $cn['status'] === 'DRAFT';
        $canCancel = in_array($group, ['accountant','administrator'], true) && $cn['status'] === 'DRAFT';
        $this->view->setLayout($this->roleLayout());
        $this->view->render('CreditNotes/view', [
            'page_title' => 'Credit Note ' . $cn['cn_no'],
            'cn'         => $cn,
            'lines'      => $lines,
            'can_issue'  => $canIssue,
            'can_cancel' => $canCancel,
        ]);
    }

    public function draftAction($saleId = 0)
    {
        $saleId = (int)$saleId;
        $group = strtolower(trim($this->currentUserGroup()));
        if (!in_array($group, ['accountant','administrator','finance manager'], true)) {
            $this->fb('Only Accountant/FM/Admin can draft credit notes.'); return;
        }
        if (!class_exists('Sales')) require_once ROOT . '/app/models/Sales.php';
        $sale = (new Sales())->byId($saleId);
        if (empty($sale) || !in_array($sale['invoice_workflow_status'], ['ISSUED','PART_PAID','OVERDUE','PAID_LATE','PAID'], true)) {
            $this->fb('Sale not eligible for credit note.'); return;
        }
        $items = (new Sales())->itemsFor($saleId);
        $this->view->setLayout($this->roleLayout());
        $this->view->render('CreditNotes/draft', [
            'page_title' => 'New Credit Note — ' . $sale['sale_no'],
            'sale'       => $sale,
            'sale_items' => $items,
            'reasons'    => CreditNotes::REASONS,
        ]);
    }

    public function saveDraftAjAction()
    {
        header('Content-Type: application/json');
        try {
            $group = strtolower(trim($this->currentUserGroup()));
            if (!in_array($group, ['accountant','administrator','finance manager'], true)) throw new RuntimeException('Access denied.');
            $lines = json_decode((string)($_POST['lines'] ?? '[]'), true);
            if (!is_array($lines)) $lines = [];
            $id = (new CreditNotes())->draft([
                'sale_id'   => (int)($_POST['sale_id'] ?? 0),
                'reason'    => (string)($_POST['reason'] ?? 'RETURN'),
                'narrative' => (string)($_POST['narrative'] ?? ''),
                'lines'     => $lines,
            ], $this->currentUserId(), $_SESSION['full_name'] ?? '');
            echo json_encode(['ok' => true, 'cn_id' => $id]);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function issueAjAction()
    {
        header('Content-Type: application/json');
        try {
            $group = strtolower(trim($this->currentUserGroup()));
            if (!in_array($group, ['accountant','administrator'], true)) throw new RuntimeException('Only Accountant/Admin can issue.');
            $cnId = (int)($_POST['cn_id'] ?? 0);
            if ($cnId <= 0) throw new InvalidArgumentException('cn_id required.');
            $r = (new CreditNotes())->issue($cnId, [
                'efd_receipt_no'         => (string)($_POST['efd_receipt_no'] ?? ''),
                'efd_date'               => (string)($_POST['efd_date'] ?? ''),
                'tra_verification_code'  => (string)($_POST['tra_verification_code'] ?? ''),
                'original_efd_receipt_no'=> (string)($_POST['original_efd_receipt_no'] ?? ''),
            ], $this->currentUserId(), $_SESSION['full_name'] ?? '');
            echo json_encode($r);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function cancelAjAction()
    {
        header('Content-Type: application/json');
        try {
            $group = strtolower(trim($this->currentUserGroup()));
            if (!in_array($group, ['accountant','administrator'], true)) throw new RuntimeException('Only Accountant/Admin can cancel.');
            $cnId = (int)($_POST['cn_id'] ?? 0);
            if ($cnId <= 0) throw new InvalidArgumentException('cn_id required.');
            (new CreditNotes())->cancel($cnId, $this->currentUserId());
            echo json_encode(['ok' => true]);
        } catch (\Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    private function fb(string $msg): void
    {
        $this->view->setLayout($this->roleLayout());
        $this->view->render('generals/fb_page', [
            'page_title' => 'Credit Notes',
            'fb_msg'     => '<div class="alert alert-warning">' . htmlspecialchars($msg) . '</div>',
        ]);
    }
}
