<?php
/**
 * WorksPhasesController — phase planner for Works projects.
 *
 *   /WorksPhases/plan/{project_id}   list all phases on a project + add-phase form
 *   /WorksPhases/view/{phase_id}     phase detail: BOQ items attached + activities + CRs
 *   /WorksPhases/createAj            POST project_id + title + code + planned_start/end
 *   /WorksPhases/attachBoqItemAj     POST phase_id + boq_item_id + planned_qty + notes
 *   /WorksPhases/addActivityAj       POST phase_id + title + code + unit + planned_qty + linked_boq_item_id
 *   /WorksPhases/markActiveAj        POST id
 *   /WorksPhases/markClosedAj        POST id
 */
class WorksPhasesController extends Controller
{
    /** Cross-project phase index — see which phases are Planned/Active across the org. */
    public function indexAction()
    {
        $db = new DB();
        $rows = $db->mySelect(
            "SELECT ph.c0d, ph.phase_no, ph.code, ph.title, ph.status,
                    ph.planned_start, ph.planned_end,
                    p.c0d project_id, p.project_no, p.project_name
               FROM works_phases ph
               JOIN c_projects  p  ON p.c0d = ph.project_id AND p.deleted = 0
              WHERE ph.deleted = 0
              ORDER BY ph.status = 'ACTIVE' DESC, ph.status = 'PLANNED' DESC, ph.planned_start DESC",
            []
        ) ?: [];
        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksPhases/index', [
            'page_title' => 'Phases · all projects',
            'rows'       => $rows,
        ]);
    }

    public function planAction($projectId = 0)
    {
        $projectId = (int)$projectId;
        $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);

        // Load CR + BOQ item counts per phase for the list
        $summary = [];
        foreach ($phases as $ph) {
            $phId = (int)$ph['c0d'];
            $summary[$phId] = [
                'boq_items'  => count($wp->boqItemsFor($phId)),
                'activities' => count($wp->activitiesFor($phId)),
                'crs'        => (int)($db->mySelect("SELECT COUNT(*) n FROM works_crs WHERE phase_id = :p AND deleted = 0", [':p' => $phId])[0]['n'] ?? 0),
            ];
        }

        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksPhases/plan', [
            'page_title' => 'Phase Planning · ' . ($prj[0]['project_no'] ?? ''),
            'project'    => $prj[0],
            'phases'     => $phases,
            'summary'    => $summary,
        ]);
    }

    public function viewAction($phaseId = 0)
    {
        $phaseId = (int)$phaseId;
        $wp    = new WorksPhases();
        $phase = $wp->findById($phaseId);
        if (!$phase) {
            $this->view->setLayout($this->roleLayout());
            $this->view->render('generals/fb_page', ['fb_msg' => '<div class="alert alert-danger">Phase 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)$phase['project_id']]);

        // BOQ items not yet attached (for the picker)
        if (!class_exists('WorksBoq')) require_once ROOT . '/app/models/WorksBoq.php';
        $wb  = new WorksBoq();
        $boq = $wb->findByProject((int)$phase['project_id']);
        $availableItems = [];
        if ($boq) {
            $attached = array_column($wp->boqItemsFor($phaseId), 'boq_item_id');
            foreach ($wb->itemsFor((int)$boq['c0d']) as $it) {
                if (!in_array((int)$it['c0d'], array_map('intval', $attached), true)) $availableItems[] = $it;
            }
        }

        // CRs on this phase
        $crs = $db->mySelect(
            "SELECT c0d, cr_no, title, version, status, grand_total, submitted_on, activated_on
               FROM works_crs WHERE phase_id = :p AND deleted = 0 ORDER BY version DESC, c0d DESC",
            [':p' => $phaseId]
        ) ?: [];

        $this->view->setLayout($this->roleLayout());
        $this->view->render('WorksPhases/view', [
            'page_title'      => 'Phase · ' . $phase['title'],
            'phase'           => $phase,
            'project'         => $prj[0] ?? [],
            'boq_items'       => $wp->boqItemsFor($phaseId),
            'available_items' => $availableItems,
            'activities'      => $wp->activitiesFor($phaseId),
            'crs'             => $crs,
        ]);
    }

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

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

    public function attachBoqItemAjAction()
    {
        header('Content-Type: application/json');
        try {
            $id = (new WorksPhases())->attachBoqItem(
                (int)($_POST['phase_id'] ?? 0),
                (int)($_POST['boq_item_id'] ?? 0),
                (float)($_POST['planned_qty'] ?? 0),
                (string)($_POST['notes'] ?? '')
            );
            echo json_encode(['ok' => true, 'id' => $id]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    public function addActivityAjAction()
    {
        header('Content-Type: application/json');
        try {
            $id = (new WorksPhases())->addActivity(
                (int)($_POST['phase_id'] ?? 0),
                [
                    'title'              => (string)($_POST['title'] ?? ''),
                    'code'               => (string)($_POST['code'] ?? ''),
                    'description'        => (string)($_POST['description'] ?? ''),
                    'unit'               => (string)($_POST['unit'] ?? ''),
                    'planned_qty'        => (float)($_POST['planned_qty'] ?? 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 markClosedAjAction()
    {
        header('Content-Type: application/json');
        try {
            (new WorksPhases())->markClosed((int)($_POST['id'] ?? 0), (int)($_SESSION['user_id'] ?? 0));
            echo json_encode(['ok' => true]);
        } catch (Throwable $e) { echo json_encode(['ok' => false, 'msg' => $e->getMessage()]); }
    }

    /** POST id → close a phase after asserting every CR on it is CLOSED / SUPERSEDED / CANCELLED. */
    public function closeAjAction()
    {
        header('Content-Type: application/json');
        try {
            $res = (new WorksPhases())->close(
                (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()]); }
    }
}
