<?php
class AssetsController extends Controller
{
    public function indexAction()
    {
        $filter = ['status' => (string)($_GET['status'] ?? ''), 'category_id' => (int)($_GET['category_id'] ?? 0), 'q' => trim((string)($_GET['q'] ?? ''))];
        $m = new Assets();
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/index', [
            'page_title' => 'Fixed Assets · Register',
            'rows'       => $m->listAll($filter),
            'categories' => $m->categories(),
            'filter'     => $filter,
        ]);
    }

    public function addAction()
    {
        $m = new Assets();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
            $userId = (int)($_SESSION['user_id'] ?? 0);
            $id = $m->create($_POST, $userId);
            if ($id > 0) { header('Location: ' . PROOT . 'Assets/view/' . $id); return; }
        }
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/form', [
            'page_title' => 'Add Asset',
            'categories' => $m->categories(),
            'asset'      => null,
        ]);
    }

    /**
     * Slice 8b-3 · Project-scoped add — the ProjectStarter Services checklist points here.
     * Pre-fills project_id so the added asset is scoped to that project (needed for PM plans).
     * Passes the project header so the view can show context; also lists assets already on the project.
     */
    public function addForProjectAction($projectId = 0)
    {
        $projectId = (int)$projectId;
        $db = new DB();
        $prj = $db->mySelect(
            "SELECT c0d, project_no, project_name, project_type, project_customer
               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;
        }
        $m = new Assets();
        if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
            $data = $_POST;
            $data['project_id'] = $projectId; // Force scope regardless of what was POSTed
            $userId = (int)($_SESSION['user_id'] ?? 0);
            $id = $m->create($data, $userId);
            if ($id > 0) { header('Location: ' . PROOT . 'Assets/addForProject/' . $projectId . '?added=' . $id); return; }
        }
        $existing = $db->mySelect(
            "SELECT c0d, asset_no, name, status FROM assets WHERE project_id = :p AND deleted = 0 ORDER BY c0d DESC",
            [':p' => $projectId]
        ) ?: [];
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/form', [
            'page_title'    => 'Add asset · ' . ($prj[0]['project_no'] ?? ''),
            'categories'    => $m->categories(),
            'asset'         => null,
            'project'       => $prj[0],
            'project_scope' => true,
            'existing_for_project' => $existing,
            'added_id'      => (int)($_GET['added'] ?? 0),
        ]);
    }

    public function viewAction($id = 0)
    {
        $id = (int)$id;
        $m = new Assets();
        $asset = $m->find($id);
        if (!$asset) { header('HTTP/1.1 404 Not Found'); echo 'Asset not found'; return; }
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/view', [
            'page_title'  => 'Asset · ' . htmlspecialchars($asset['asset_no']),
            'asset'       => $asset,
            'dep_history' => $m->depreciationHistory($id),
            'disposal'    => $m->findDisposal($id),
        ]);
    }

    public function categoriesAction()
    {
        $m = new Assets();
        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/categories', [
            'page_title' => 'Asset Categories',
            'categories' => $m->categories(),
        ]);
    }

    public function runDepreciationAction()
    {
        $year  = (int)($_GET['year']  ?? date('Y'));
        $month = (int)($_GET['month'] ?? date('n'));
        $m = new Assets();
        $preview = $m->previewDepreciation($year, $month);
        $totalAmt = 0.0; foreach ($preview as $p) $totalAmt += (float)$p['depreciation_amount'];

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/run_depreciation', [
            'page_title'   => 'Run Monthly Depreciation',
            'year'         => $year,
            'month'        => $month,
            'preview'      => $preview,
            'total_amount' => $totalAmt,
        ]);
    }

    public function runDepreciationAjAction()
    {
        header('Content-Type: application/json');
        try {
            $year  = (int)($_POST['year']  ?? 0);
            $month = (int)($_POST['month'] ?? 0);
            if ($year < 2000 || $month < 1 || $month > 12) throw new InvalidArgumentException('Invalid period.');
            $userId   = (int)($_SESSION['user_id'] ?? 0);
            $userName = (string)($_SESSION['full_name'] ?? '');
            $res = (new Assets())->runDepreciation($year, $month, $userId, $userName);
            echo json_encode(['ok' => true] + $res);
        } catch (Throwable $e) {
            echo json_encode(['ok' => false, 'msg' => $e->getMessage()]);
        }
    }

    /* ── Disposal ──────────────────────────────────────────────────────── */

    public function disposeAction($id = 0)
    {
        $id = (int)$id;
        $m = new Assets();
        $a = $m->find($id);
        if (!$a) { header('HTTP/1.1 404 Not Found'); echo 'Asset not found'; return; }
        if ($a['status'] === 'DISPOSED') { header('Location: ' . PROOT . 'Assets/view/' . $id); return; }

        // Bank COAs (dropdown for where sale proceeds land)
        $db = new DB();
        $banks = $db->mySelect("SELECT c0d, account_code, account_name FROM chart_of_accounts WHERE is_bank = 1 AND is_active = 1 ORDER BY account_code", []);

        $this->view->setLayout($this->roleLayout());
        $this->view->render('Assets/dispose', [
            'page_title' => 'Dispose · ' . htmlspecialchars($a['asset_no']),
            'asset'      => $a,
            'nbv'        => (float)$a['purchase_cost'] - (float)$a['accumulated_depreciation'],
            'banks'      => $banks ?: [],
        ]);
    }

    public function disposeAjAction()
    {
        header('Content-Type: application/json');
        try {
            $assetId       = (int)($_POST['asset_id'] ?? 0);
            $disposalDate  = trim((string)($_POST['disposal_date'] ?? date('Y-m-d')));
            $method        = trim((string)($_POST['disposal_method'] ?? 'SALE'));
            $salePrice     = (float)($_POST['sale_price'] ?? 0);
            $buyerName     = trim((string)($_POST['buyer_name'] ?? ''));
            $bankAccountId = (int)($_POST['bank_account_id'] ?? 0) ?: null;
            $notes         = trim((string)($_POST['notes'] ?? ''));
            if ($assetId <= 0) throw new InvalidArgumentException('Missing asset id.');
            if (!in_array($method, ['SALE','SCRAP','DONATION','WRITE_OFF'], true)) throw new InvalidArgumentException('Invalid disposal method.');
            if ($method !== 'SALE') $salePrice = 0;

            $userId   = (int)($_SESSION['user_id'] ?? 0);
            $userName = (string)($_SESSION['full_name'] ?? '');

            $res = (new Assets())->disposeAsset($assetId, $disposalDate, $method, $salePrice, $buyerName, $bankAccountId, $notes, $userId, $userName);
            echo json_encode(['ok' => true] + $res);
        } catch (Throwable $e) {
            echo json_encode(['ok' => false, 'msg' => $e->getMessage()]);
        }
    }

    /* ── Exports ───────────────────────────────────────────────────────── */

    public function xlsxAction() { $this->exportRegister('xlsx'); }
    public function pdfAction()  { $this->exportRegister('pdf');  }

    private function exportRegister(string $format): void
    {
        $filter = ['status' => (string)($_GET['status'] ?? ''), 'category_id' => (int)($_GET['category_id'] ?? 0), 'q' => trim((string)($_GET['q'] ?? ''))];
        $rows = (new Assets())->listAll($filter);
        $data = []; $sumCost = 0; $sumAcc = 0; $sumNbv = 0;
        foreach ($rows as $a) {
            $nbv = (float)$a['purchase_cost'] - (float)$a['accumulated_depreciation'];
            $data[] = [$a['asset_no'], $a['name'], $a['category_name'], $a['purchase_date'],
                       (float)$a['purchase_cost'], (float)$a['accumulated_depreciation'], $nbv,
                       $a['status'], (string)$a['custodian_name']];
            $sumCost += (float)$a['purchase_cost']; $sumAcc += (float)$a['accumulated_depreciation']; $sumNbv += $nbv;
        }
        $columns = [
            ['label' => 'Asset #',   'width' => 16, 'align' => 'L'],
            ['label' => 'Name',      'width' => 34, 'align' => 'L'],
            ['label' => 'Category',  'width' => 22, 'align' => 'L'],
            ['label' => 'Purchased', 'width' => 14, 'align' => 'L', 'type' => 'date'],
            ['label' => 'Cost',      'width' => 18, 'align' => 'R', 'type' => 'money'],
            ['label' => 'Acc. Dep.',  'width' => 18, 'align' => 'R', 'type' => 'money'],
            ['label' => 'NBV',       'width' => 18, 'align' => 'R', 'type' => 'money'],
            ['label' => 'Status',    'width' => 14, 'align' => 'L'],
            ['label' => 'Custodian', 'width' => 22, 'align' => 'L'],
        ];
        $totals = [['label' => 'Totals', 'values' => [null, null, null, null, $sumCost, $sumAcc, $sumNbv, null, null]]];
        $title = 'Fixed Assets Register';
        $sub   = 'As at ' . date('Y-m-d') . '  ·  ' . count($rows) . ' asset(s)';
        $fname = 'fixed_assets_register_' . date('Y-m-d');
        if ($format === 'xlsx') {
            ExportHelper::xlsxDownload($fname . '.xlsx', 'Assets', $columns, $data, $totals, ['title' => $title, 'subtitle' => $sub]);
        } else {
            ExportHelper::pdfDownload($fname . '.pdf', $title, $sub, $columns, $data, $totals, 'L');
        }
    }
}
