<?php
/**
 * ProjectServiceOverheadAnnotations · Slice 8Z-v.
 *
 * PM's per-line annotations against the tender's overhead pool. The pool itself
 * (pricing_version_overheads) is live-read from the tender — this table just
 * stores the PM's actual-vs-bid notes + a projected actual amount.
 */
class ProjectServiceOverheadAnnotations extends Model
{
    /** Fetch annotations for one project keyed by tender_overhead_id for O(1) merge on the view. */
    public function forProjectKeyed(int $projectId): array
    {
        $db = new DB();
        $rs = $db->mySelect(
            "SELECT * FROM project_service_overhead_annotations WHERE project_id = :p",
            [':p' => $projectId]
        ) ?: [];
        $out = [];
        foreach ($rs as $r) $out[(int)$r['tender_overhead_id']] = $r;
        return $out;
    }

    /** Upsert one annotation. Returns ['ok' => bool, 'id' => int]. */
    public function save(int $projectId, int $tenderOverheadId, array $d, int $userId, string $userName): array
    {
        if ($projectId <= 0 || $tenderOverheadId <= 0) return ['ok' => false, 'msg' => 'project_id + tender_overhead_id required.'];
        $params = [
            ':p'      => $projectId,
            ':toh'    => $tenderOverheadId,
            ':amt'    => (isset($d['actual_amount']) && $d['actual_amount'] !== '') ? (float)$d['actual_amount'] : null,
            ':notes'  => trim((string)($d['notes'] ?? '')) ?: null,
            ':eb'     => $userId,
            ':ebn'    => $userName,
        ];
        $db = new DB();
        $existing = $db->mySelect(
            "SELECT c0d FROM project_service_overhead_annotations WHERE project_id = :p AND tender_overhead_id = :toh",
            [':p' => $projectId, ':toh' => $tenderOverheadId]
        );
        if (!empty($existing)) {
            // UPDATE only references :amt, :notes, :eb, :id — drop the seeded :p / :toh / :ebn
            // so PDO's strict param binding doesn't reject the query.
            $uParams = [
                ':amt'   => $params[':amt'],
                ':notes' => $params[':notes'],
                ':eb'    => $params[':eb'],
                ':id'    => (int)$existing[0]['c0d'],
            ];
            $db->insertUpdate(
                "UPDATE project_service_overhead_annotations
                    SET actual_amount = :amt, notes = :notes, edited_by = :eb, edited_on = NOW()
                  WHERE c0d = :id",
                $uParams
            );
            return ['ok' => true, 'id' => (int)$existing[0]['c0d']];
        }
        $params[':cb']  = $userId;
        $params[':cbn'] = $userName;
        // UPDATE-only bindings are unused on INSERT — strip them
        unset($params[':eb'], $params[':ebn']);
        $r = $db->insertUpdate(
            "INSERT INTO project_service_overhead_annotations
                (project_id, tender_overhead_id, actual_amount, notes, created_by, created_by_name, created_on)
             VALUES (:p, :toh, :amt, :notes, :cb, :cbn, NOW())",
            $params
        );
        return ['ok' => true, 'id' => (int)($r['last_id'] ?? 0)];
    }
}
