<?php
/**
 * WorksCrsController — Consolidated Request authoring for Works phases.
 *
 *   /WorksCrs/create/{project_id}?phase_id=X   pick phase + title, then create + redirect to view
 *   /WorksCrs/view/{cr_id}                     detail with 7-pillar editor + activities + submit
 *   /WorksCrs/createAj                         POST project_id + phase_id + title
 *   /WorksCrs/addLineAj                        POST cr_id + pillar + line-shape data
 *   /WorksCrs/deleteLineAj                     POST cr_id + pillar + line_id
 *   /WorksCrs/addActivityAj                    POST cr_id + title + description + unit + planned_qty + linked_boq_item_id
 *   /WorksCrs/submitAj                         POST id → chain
 */
class WorksCrsController extends Controller
{
    /** Cross-project CR index — every CR grouped by status; the closest thing to a CR queue. */
    public function indexAction()
    {
        $db = new DB();
        $rows = $db->mySelect(
            "SELECT c.c0d, c.cr_no, c.title, c.version, c.status, c.grand_total, c.submitted_on, c.activated_on,
                    p.c0d project_id, p.project_no, p.project_name,
                    ph.phase_no, ph.title phase_title
               FROM works_crs c
               JOIN c_projects   p  ON p.c0d = c.project_id AND p.deleted = 0
               LEFT JOIN works_phases ph ON ph.c0d = c.phase_id
              WHERE c.deleted = 0
              ORDER BY c.status = 'ACTIVE' DESC, c.status = 'SUBMITTED' DESC, c.status = 'APPROVED' DESC,
                       c.c0d DESC",
            []
        ) ?: [];
        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksCrs/index', [
            'page_title' => 'Consolidated Requests · all projects',
            'rows'       => $rows,
        ]);
    }

    public function createAction($projectId = 0)
    {
        $projectId = (int)$projectId;
        $preferredPhaseId = (int)($_GET['phase_id'] ?? 0);
        $db = new DB();
        $prj = $db->mySelect(
            "SELECT c0d, project_no, project_name, project_type, project_customer, currency
               FROM c_projects WHERE c0d = :p AND deleted = 0",
            [':p' => $projectId]
        );
        if (empty($prj)) {
            $this->view->setLayout($this->roleLayout());
            $this->view->render('generals/fb_page', ['fb_msg' => '<div class="alert alert-danger">Project not found.</div>']);
            return;
        }
        $wp = new WorksPhases();
        $phases = $wp->listForProject($projectId);
        // Skip CLOSED / CANCELLED phases from the picker
        $phases = array_values(array_filter($phases, fn($p) => in_array($p['status'], ['PLANNED','ACTIVE'], true)));

        $existing = (new WorksCrs())->listForProject($projectId);

        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksCrs/create', [
            'page_title'         => 'New CR · ' . ($prj[0]['project_no'] ?? ''),
            'project'            => $prj[0],
            'phases'             => $phases,
            'preferred_phase_id' => $preferredPhaseId,
            'existing'           => $existing,
        ]);
    }

    public function viewAction($crId = 0)
    {
        $crId = (int)$crId;
        $wc  = new WorksCrs();
        $cr  = $wc->findById($crId);
        if (!$cr) {
            $this->view->setLayout($this->roleLayout());
            $this->view->render('generals/fb_page', ['fb_msg' => '<div class="alert alert-danger">CR not found.</div>']);
            return;
        }
        $db  = new DB();
        $prj = $db->mySelect("SELECT c0d, project_no, project_name, currency FROM c_projects WHERE c0d = :p", [':p' => (int)$cr['project_id']]);
        $ph  = (new WorksPhases())->findById((int)$cr['phase_id']);

        // Activities from the phase (for the linked-activity picker on CR activity form)
        $phaseActivities = (new WorksPhases())->activitiesFor((int)$cr['phase_id']);
        // BOQ items on the phase (for linking activities to BOQ)
        $phaseBoqItems = (new WorksPhases())->boqItemsFor((int)$cr['phase_id']);

        $allLines  = $wc->allLines($crId);
        $activities = $wc->activitiesFor($crId);

        // Chain history if submitted
        $approval = []; $history = []; $steps = [];
        if ((int)$cr['approval_id'] > 0) {
            if (!class_exists('ApprovalChain')) require_once ROOT . '/app/models/ApprovalChain.php';
            $ac = new ApprovalChain();
            $approval = $ac->approvalById((int)$cr['approval_id']);
            $history  = $ac->historyFor((int)$cr['approval_id']);
            if (!empty($approval)) $steps = $ac->stepsForChain((int)$approval['chain_id']);
        }

        $group      = strtoupper((string)($_SESSION['user_group_name'] ?? ''));
        $isCreator  = (int)$cr['created_by'] === $this->currentUserId();
        $canEdit    = $cr['status'] === 'DRAFT' && ($isCreator || in_array($group, ['ADMINISTRATOR'], true));
        $canSubmit  = $cr['status'] === 'DRAFT' && (float)$cr['grand_total'] > 0 && count($activities) > 0
                      && ($isCreator || in_array($group, ['ADMINISTRATOR'], true));

        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksCrs/view', [
            'page_title'       => $cr['cr_no'] . ' · ' . $cr['title'],
            'cr'               => $cr,
            'phase'            => $ph,
            'project'          => $prj[0] ?? [],
            'lines'            => $allLines,
            'activities'       => $activities,
            'phase_activities' => $phaseActivities,
            'phase_boq_items'  => $phaseBoqItems,
            'pillars'          => WorksCrs::PILLARS,
            'approval'         => $approval,
            'history'          => $history,
            'steps'            => $steps,
            'can_edit'         => $canEdit,
            'can_submit'       => $canSubmit,
            'variance'         => $wc->closureVarianceFor($crId),
        ]);
    }

    /* ── AJAX endpoints ─────────────────────────────────────────────── */

    public function createAjAction()
    {
        header('Content-Type: application/json');
        try {
            $id = (new WorksCrs())->draft(
                (int)($_POST['project_id'] ?? 0),
                (int)($_POST['phase_id'] ?? 0),
                [
                    'title' => (string)($_POST['title'] ?? ''),
                    'notes' => (string)($_POST['notes'] ?? ''),
                ],
                (int)($_SESSION['user_id'] ?? 0),
                (string)($_SESSION['full_name'] ?? '')
            );
            echo json_encode(['ok' => true, 'id' => $id]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function addLineAjAction()
    {
        header('Content-Type: application/json');
        try {
            $id = (new WorksCrs())->addLine(
                (int)($_POST['cr_id'] ?? 0),
                (string)($_POST['pillar'] ?? ''),
                $_POST
            );
            echo json_encode(['ok' => true, 'id' => $id]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function deleteLineAjAction()
    {
        header('Content-Type: application/json');
        try {
            (new WorksCrs())->deleteLine(
                (int)($_POST['cr_id'] ?? 0),
                (string)($_POST['pillar'] ?? ''),
                (int)($_POST['line_id'] ?? 0)
            );
            echo json_encode(['ok' => true]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function addActivityAjAction()
    {
        header('Content-Type: application/json');
        try {
            $id = (new WorksCrs())->addActivity(
                (int)($_POST['cr_id'] ?? 0),
                [
                    'title'                    => (string)($_POST['title'] ?? ''),
                    'description'              => (string)($_POST['description'] ?? ''),
                    'unit'                     => (string)($_POST['unit'] ?? ''),
                    'planned_qty'              => (float)($_POST['planned_qty'] ?? 0),
                    'linked_phase_activity_id' => (int)($_POST['linked_phase_activity_id'] ?? 0),
                    'linked_boq_item_id'       => (int)($_POST['linked_boq_item_id'] ?? 0),
                ]
            );
            echo json_encode(['ok' => true, 'id' => $id]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function submitAjAction()
    {
        header('Content-Type: application/json');
        try {
            $res = (new WorksCrs())->submitForApproval(
                (int)($_POST['id'] ?? 0),
                (int)($_SESSION['user_id'] ?? 0),
                (string)($_SESSION['full_name'] ?? ''),
                (string)($_SESSION['user_group_name'] ?? '')
            );
            echo json_encode($res);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    /* ── Fulfilment surfaces (Slice 8c-Fulfil) ─────────────────────────── */

    /**
     * /WorksCrs/fulfil/{crId} — the fulfilment dashboard.
     *   • per-pillar progress bars (budget / sourced / delivered)
     *   • sourceable-line picker for MATERIALS / TOOLS / SUBCONTRACTS / EQUIPMENT-rented
     *   • LPOs already drafted from this CR
     *   • on-site delivery register (works_phase_items_issued)
     */
    public function fulfilAction($crId = 0)
    {
        $crId = (int)$crId;
        $wc   = new WorksCrs();
        $cr   = $wc->findById($crId);
        if (!$cr) {
            $this->view->setLayout($this->roleLayout());
            $this->view->render('generals/fb_page', ['fb_msg' => '<div class="alert alert-danger">CR not found.</div>']);
            return;
        }
        if (!class_exists('WorksCrFulfilment')) require_once ROOT . '/app/models/WorksCrFulfilment.php';
        $wf = new WorksCrFulfilment();

        $db = new DB();
        $prj = $db->mySelect(
            "SELECT c0d, project_no, project_name, currency FROM c_projects WHERE c0d = :p",
            [':p' => (int)$cr['project_id']]
        );
        $ph  = (new WorksPhases())->findById((int)$cr['phase_id']);
        // Vendor dropdown source
        $vendors = $db->mySelect(
            "SELECT c0d, vendor_name FROM vendors WHERE deleted = 0 ORDER BY vendor_name",
            []
        ) ?: [];

        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksCrs/fulfil', [
            'page_title'       => 'Fulfil · ' . $cr['cr_no'],
            'cr'               => $cr,
            'project'          => $prj[0] ?? [],
            'phase'            => $ph ?: [],
            'progress'         => $wf->progressPerPillar($crId),
            'sourceable_lines' => $wf->sourceableLines($crId),
            'lpos'             => $wf->lposFor($crId),
            'issued'           => $wf->issuedFor($crId),
            'payments'         => $wf->paymentsFor($crId),
            'vendors'          => $vendors,
        ]);
    }

    /**
     * POST cr_id + pillar + vendor_id + vendor_name + lines[] (each {line_id, qty, unit_price}).
     * Delegates to WorksCrFulfilment::draftLpoFromCrLines.
     */
    public function draftLpoAjAction()
    {
        header('Content-Type: application/json');
        try {
            if (!class_exists('WorksCrFulfilment')) require_once ROOT . '/app/models/WorksCrFulfilment.php';
            $wf = new WorksCrFulfilment();
            $res = $wf->draftLpoFromCrLines(
                (int)($_POST['cr_id']    ?? 0),
                (string)($_POST['pillar'] ?? ''),
                [
                    'vendor_id'   => (int)($_POST['vendor_id'] ?? 0),
                    'vendor_name' => (string)($_POST['vendor_name'] ?? ''),
                    'currency'    => (string)($_POST['currency'] ?? 'TZS'),
                ],
                (array)($_POST['lines'] ?? []),
                (int)($_SESSION['user_id'] ?? 0),
                (string)($_SESSION['full_name'] ?? '')
            );
            echo json_encode($res);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    /** POST id + reason → close an ACTIVE CR after snapshotting per-pillar variance. */
    public function closeAjAction()
    {
        header('Content-Type: application/json');
        try {
            $res = (new WorksCrs())->close(
                (int)($_POST['id'] ?? 0),
                (string)($_POST['reason'] ?? ''),
                (int)($_SESSION['user_id'] ?? 0),
                (string)($_SESSION['full_name'] ?? ''),
                (string)($_SESSION['user_group_name'] ?? '')
            );
            echo json_encode($res);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    /** POST lpo_item_id + qty + issued_on + notes → creates a delivery register entry. */
    public function recordIssueAjAction()
    {
        header('Content-Type: application/json');
        try {
            if (!class_exists('WorksCrFulfilment')) require_once ROOT . '/app/models/WorksCrFulfilment.php';
            $id = (new WorksCrFulfilment())->recordIssue(
                [
                    'lpo_item_id' => (int)($_POST['lpo_item_id'] ?? 0),
                    'qty'         => (float)($_POST['qty'] ?? 0),
                    'issued_on'   => (string)($_POST['issued_on'] ?? date('Y-m-d')),
                    'notes'       => (string)($_POST['notes'] ?? ''),
                ],
                (int)($_SESSION['user_id'] ?? 0),
                (string)($_SESSION['full_name'] ?? '')
            );
            echo json_encode(['ok' => true, 'id' => $id]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }
}
