<?php
require_once __DIR__ . '/../../includes/bootstrap.php';
require_login();

$pageTitle = 'Rate Contracts';

/**
 * rate_contracts.php - manage the NORMALISED rate tables.
 *
 *   rate_plans        the CONTRACT  ("STO BB", "RACK HB", "BAOBAB VSTO BB")
 *   rate_plan_prices  its PRICES    (per room type, per season)
 *   agents.rate_plan_id             which contract each agent is on
 *
 * Why this is a separate page from rate_plans.php:
 * a rack rate is a price on a room type; a CONTRACT is a negotiated agreement
 * that many agents share and that carries its own prices. Change STO BB once
 * and all ~780 agents on it follow. Duplicating a rate row per agent - which
 * is what the legacy flat table forced - is exactly the problem this removes.
 *
 * rate_plans.php still manages the legacy room_type_rate_plans table, which
 * remains the home of the public/rack rates. fetch_rate_plan() reads both.
 */

if (!function_exists('h')) {
    function h($value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); }
}
if (!function_exists('money_fmt')) {
    function money_fmt($amount): string { return number_format((float)$amount, 2); }
}
if (!function_exists('roomz_meal_plans')) {
    function roomz_meal_plans(): array
    {
        return ['BB' => 'BB - Bed + Breakfast', 'HB' => 'HB - Half Board', 'FB' => 'FB - Full Board'];
    }
}
if (!function_exists('safe_meal_plan')) {
    function safe_meal_plan($value): string
    {
        $value = strtoupper(trim((string)$value));
        return in_array($value, ['HB', 'BB', 'FB'], true) ? $value : 'HB';
    }
}
if (!function_exists('rc_agent_name')) {
    function rc_agent_name(array $row): string
    {
        $name = trim((string)($row['firstname'] ?? '') . ' ' . (string)($row['lastname'] ?? ''));
        if ($name === '') $name = trim((string)($row['agent'] ?? ''));
        return $name !== '' ? $name : ('Agent #' . (int)($row['id'] ?? 0));
    }
}
if (!function_exists('rc_column_exists')) {
    function rc_column_exists(PDO $pdo, string $table, string $col): bool
    {
        static $cache = [];
        $k = $table . '.' . $col;
        if (array_key_exists($k, $cache)) return $cache[$k];
        try {
            $s = $pdo->prepare("SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS
                                WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = :t AND COLUMN_NAME = :c");
            $s->execute([':t' => $table, ':c' => $col]);
            $cache[$k] = ((int)$s->fetchColumn() > 0);
        } catch (Throwable $e) { $cache[$k] = false; }
        return $cache[$k];
    }
}
if (!function_exists('rc_tables_ready')) {
    function rc_tables_ready(PDO $pdo): bool
    {
        try {
            $s = $pdo->query("SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES
                              WHERE TABLE_SCHEMA = DATABASE()
                                AND TABLE_NAME IN ('rate_plans','rate_plan_prices')");
            return ((int)$s->fetchColumn() === 2);
        } catch (Throwable $e) { return false; }
    }
}

/* Agent name expression built from columns that actually exist. */
if (!function_exists('rc_agent_name_expr')) {
    function rc_agent_name_expr(PDO $pdo, string $alias = 'a'): string
    {
        if (rc_column_exists($pdo, 'agents', 'firstname') && rc_column_exists($pdo, 'agents', 'lastname')) {
            return "TRIM(CONCAT(COALESCE({$alias}.firstname,''),' ',COALESCE({$alias}.lastname,'')))";
        }
        foreach (['agent', 'name', 'company_name', 'company'] as $c) {
            if (rc_column_exists($pdo, 'agents', $c)) return "TRIM(COALESCE({$alias}.`{$c}`,''))";
        }
        return "CONCAT('Agent #', {$alias}.id)";
    }
}

$errors = [];
$notices = [];

if (!rc_tables_ready($pdo)) {
    require_once __DIR__ . '/../../includes/header.php';
    echo '<div class="alert alert-warning m-3">The <code>rate_plans</code> and <code>rate_plan_prices</code> tables do not exist yet. Run <code>01_migrate.sql</code> first.</div>';
    require_once __DIR__ . '/../../includes/footer.php';
    exit;
}

$hasIsPublic = rc_column_exists($pdo, 'rate_plans', 'is_public');
$hasAgentLink = rc_column_exists($pdo, 'agents', 'rate_plan_id');
$agentNameExpr = rc_agent_name_expr($pdo, 'a');

$roomTypes = [];
try {
    $roomTypes = $pdo->query("SELECT id, title FROM room_types ORDER BY title ASC")->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $e) { $roomTypes = []; }
$roomTypeTitle = [];
foreach ($roomTypes as $rt) $roomTypeTitle[(int)$rt['id']] = (string)$rt['title'];

/* =====================================================================
   ACTIONS
   ===================================================================== */
if (($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST') {
    $action = (string)($_POST['action'] ?? '');
    try {

        /* ---------- Save the contract itself ---------- */
        if ($action === 'save_contract') {
            $id        = (int)($_POST['contract_id'] ?? 0);
            $code      = trim((string)($_POST['code'] ?? ''));
            $title     = trim((string)($_POST['title'] ?? ''));
            $descr     = trim((string)($_POST['description'] ?? ''));
            $mealPlan  = safe_meal_plan($_POST['meal_plan'] ?? 'BB');
            $isPublic  = !empty($_POST['is_public']) ? 1 : 0;
            $status    = !empty($_POST['status']) ? 1 : 0;

            if ($code === '')  throw new RuntimeException('Code is required (it is what the migration and any import key on).');
            if ($title === '') throw new RuntimeException('Title is required.');

            if ($id > 0) {
                $sql = "UPDATE rate_plans SET code=:code, title=:title, description=:descr, meal_plan=:mp"
                     . ($hasIsPublic ? ", is_public=:pub" : "") . ", status=:st WHERE id=:id";
                $p = [':code'=>$code, ':title'=>$title, ':descr'=>$descr!==''?$descr:null, ':mp'=>$mealPlan, ':st'=>$status, ':id'=>$id];
                if ($hasIsPublic) $p[':pub'] = $isPublic;
                $pdo->prepare($sql)->execute($p);
                $notices[] = 'Contract updated.';
            } else {
                $sql = "INSERT INTO rate_plans (code, title, description, meal_plan"
                     . ($hasIsPublic ? ", is_public" : "") . ", status, created_at)
                        VALUES (:code, :title, :descr, :mp" . ($hasIsPublic ? ", :pub" : "") . ", :st, NOW())";
                $p = [':code'=>$code, ':title'=>$title, ':descr'=>$descr!==''?$descr:null, ':mp'=>$mealPlan, ':st'=>$status];
                if ($hasIsPublic) $p[':pub'] = $isPublic;
                $pdo->prepare($sql)->execute($p);
                $id = (int)$pdo->lastInsertId();
                $notices[] = 'Contract created.';
            }
            header('Location: rate_contracts.php?contract_id=' . $id);
            exit;
        }

        /* ---------- Save one season (a price row) ---------- */
        if ($action === 'save_price') {
            $priceId     = (int)($_POST['price_id'] ?? 0);
            $contractId  = (int)($_POST['contract_id'] ?? 0);
            $roomTypeIds = array_map('intval', (array)($_POST['room_type_ids'] ?? []));
            $validFrom   = trim((string)($_POST['valid_from'] ?? ''));
            $validTo     = trim((string)($_POST['valid_to'] ?? ''));
            $sharing     = (string)($_POST['sharing_rate'] ?? '');
            $single      = (string)($_POST['single_rate'] ?? '');
            $supplement  = (string)($_POST['single_supplement'] ?? '0');
            $childPct    = (string)($_POST['child_rate_percent'] ?? '50');
            $currency    = strtoupper(trim((string)($_POST['currency'] ?? 'USD')));
            $status      = !empty($_POST['status']) ? 1 : 0;

            if ($contractId <= 0) throw new RuntimeException('Contract is required.');
            if (!$roomTypeIds)    throw new RuntimeException('Select at least one room type.');
            if ($validFrom === '' || $validTo === '') throw new RuntimeException('Both season dates are required.');
            if (strtotime($validTo) < strtotime($validFrom)) throw new RuntimeException('Valid-to cannot be before valid-from.');
            foreach (['sharing_rate'=>$sharing, 'single_rate'=>$single, 'single_supplement'=>$supplement, 'child_rate_percent'=>$childPct] as $k=>$v) {
                if ($v === '' || !is_numeric($v)) throw new RuntimeException(ucwords(str_replace('_',' ',$k)) . ' must be a number.');
            }

            /*
               sharing_rate is charged PER ADULT for 2+ adults. Zero on an
               active season bills a couple 0.00 per night - the room is given
               away and nothing else in RoomZ notices. Four migrated Semper
               contracts arrived in exactly this state.
            */
            if ($status === 1 && round((float)$sharing, 2) <= 0) {
                throw new RuntimeException('Sharing rate must be greater than zero on an active season. It is charged per adult, so zero would bill two adults 0.00 per night. Set a real rate, or mark the season inactive.');
            }
            /* RoomZ uses single_rate and ignores the supplement whenever
               single_rate > 0 - having both set is dead config that looks live. */
            if (round((float)$single, 2) > 0 && round((float)$supplement, 2) > 0) {
                throw new RuntimeException('Set either a Single Rate or a Single Supplement, not both. When a Single Rate is present RoomZ uses it and ignores the supplement.');
            }

            $pdo->beginTransaction();

            if ($priceId > 0) {
                // Editing one row: it belongs to exactly one room type.
                $rt = (int)($roomTypeIds[0] ?? 0);
                $pdo->prepare("UPDATE rate_plan_prices
                    SET room_type_id=:rt, valid_from=:vf, valid_to=:vt, sharing_rate=:sh, single_rate=:sr,
                        single_supplement=:ss, child_rate_percent=:cp, currency=:cur, status=:st
                    WHERE id=:id AND rate_plan_id=:cid")
                    ->execute([':rt'=>$rt, ':vf'=>$validFrom, ':vt'=>$validTo, ':sh'=>round((float)$sharing,2),
                               ':sr'=>round((float)$single,2), ':ss'=>round((float)$supplement,2),
                               ':cp'=>round((float)$childPct,2), ':cur'=>$currency, ':st'=>$status,
                               ':id'=>$priceId, ':cid'=>$contractId]);
                $notices[] = 'Season updated.';
            } else {
                // Creating: write the same season for every selected room type.
                $ins = $pdo->prepare("INSERT INTO rate_plan_prices
                    (rate_plan_id, room_type_id, valid_from, valid_to, sharing_rate, single_rate,
                     single_supplement, child_rate_percent, currency, status, created_at)
                    VALUES (:cid, :rt, :vf, :vt, :sh, :sr, :ss, :cp, :cur, :st, NOW())
                    ON DUPLICATE KEY UPDATE
                        sharing_rate=VALUES(sharing_rate), single_rate=VALUES(single_rate),
                        single_supplement=VALUES(single_supplement),
                        child_rate_percent=VALUES(child_rate_percent),
                        currency=VALUES(currency), status=VALUES(status)");
                foreach ($roomTypeIds as $rt) {
                    if ($rt <= 0) continue;
                    $ins->execute([':cid'=>$contractId, ':rt'=>$rt, ':vf'=>$validFrom, ':vt'=>$validTo,
                                   ':sh'=>round((float)$sharing,2), ':sr'=>round((float)$single,2),
                                   ':ss'=>round((float)$supplement,2), ':cp'=>round((float)$childPct,2),
                                   ':cur'=>$currency, ':st'=>$status]);
                }
                $notices[] = 'Season saved for ' . count($roomTypeIds) . ' room type(s).';
            }

            $pdo->commit();
            header('Location: rate_contracts.php?contract_id=' . $contractId);
            exit;
        }

        /* ---------- Delete a season ---------- */
        if ($action === 'delete_price') {
            $priceId    = (int)($_POST['price_id'] ?? 0);
            $contractId = (int)($_POST['contract_id'] ?? 0);
            $pdo->prepare("DELETE FROM rate_plan_prices WHERE id=:id AND rate_plan_id=:cid")
                ->execute([':id'=>$priceId, ':cid'=>$contractId]);
            $notices[] = 'Season deleted.';
            header('Location: rate_contracts.php?contract_id=' . $contractId);
            exit;
        }

        /* ---------- Assign / unassign agents ---------- */
        if ($action === 'assign_agents') {
            if (!$hasAgentLink) throw new RuntimeException('agents.rate_plan_id does not exist - run 01_migrate.sql.');
            $contractId = (int)($_POST['contract_id'] ?? 0);
            $agentIds   = array_map('intval', (array)($_POST['agent_ids'] ?? []));
            $agentIds   = array_values(array_filter($agentIds, function($v){ return $v > 0; }));
            if ($contractId <= 0) throw new RuntimeException('Contract is required.');
            if (!$agentIds) throw new RuntimeException('Select at least one agent.');

            $ph = [];
            $params = [':cid' => $contractId];
            foreach ($agentIds as $i => $aid) { $ph[] = ':a'.$i; $params[':a'.$i] = $aid; }
            $pdo->prepare("UPDATE agents SET rate_plan_id = :cid WHERE id IN (" . implode(',', $ph) . ")")
                ->execute($params);
            $notices[] = count($agentIds) . ' agent(s) assigned to this contract.';
            header('Location: rate_contracts.php?contract_id=' . $contractId . '&tab=agents');
            exit;
        }

        if ($action === 'unassign_agent') {
            if (!$hasAgentLink) throw new RuntimeException('agents.rate_plan_id does not exist.');
            $contractId = (int)($_POST['contract_id'] ?? 0);
            $agentId    = (int)($_POST['agent_id'] ?? 0);
            $pdo->prepare("UPDATE agents SET rate_plan_id = NULL WHERE id = :aid")->execute([':aid'=>$agentId]);
            $notices[] = 'Agent removed from this contract - they will now be charged the public rate.';
            header('Location: rate_contracts.php?contract_id=' . $contractId . '&tab=agents');
            exit;
        }

    } catch (Throwable $e) {
        if ($pdo->inTransaction()) $pdo->rollBack();
        $errors[] = $e->getMessage();
    }
}

/* =====================================================================
   DATA
   ===================================================================== */
$contractId = (int)($_GET['contract_id'] ?? 0);
$tab        = (string)($_GET['tab'] ?? 'seasons');
$search     = trim((string)($_GET['q'] ?? ''));

$agentCountSql = $hasAgentLink
    ? "(SELECT COUNT(*) FROM agents ag WHERE ag.rate_plan_id = rp.id)"
    : "0";

$contracts = [];
try {
    $sql = "SELECT rp.*,
                   {$agentCountSql} AS agent_count,
                   (SELECT COUNT(*) FROM rate_plan_prices pp WHERE pp.rate_plan_id = rp.id) AS price_rows,
                   (SELECT COUNT(DISTINCT pp.room_type_id) FROM rate_plan_prices pp WHERE pp.rate_plan_id = rp.id) AS room_types,
                   (SELECT MIN(pp.valid_from) FROM rate_plan_prices pp WHERE pp.rate_plan_id = rp.id) AS first_date,
                   (SELECT MAX(pp.valid_to)   FROM rate_plan_prices pp WHERE pp.rate_plan_id = rp.id) AS last_date
            FROM rate_plans rp";
    $params = [];
    if ($search !== '') {
        $sql .= " WHERE (rp.code LIKE :q1 OR rp.title LIKE :q2)";
        $params[':q1'] = '%' . $search . '%';
        $params[':q2'] = '%' . $search . '%';
    }
    $sql .= " ORDER BY rp.status DESC, rp.title ASC";
    $st = $pdo->prepare($sql);
    $st->execute($params);
    $contracts = $st->fetchAll(PDO::FETCH_ASSOC);
} catch (Throwable $e) { $errors[] = 'Could not load contracts: ' . $e->getMessage(); }

$contract = null;
$prices = [];
$assignedAgents = [];
$unassignedAgents = [];
$gaps = [];

if ($contractId > 0) {
    try {
        $st = $pdo->prepare("SELECT * FROM rate_plans WHERE id = :id LIMIT 1");
        $st->execute([':id' => $contractId]);
        $contract = $st->fetch(PDO::FETCH_ASSOC) ?: null;

        if ($contract) {
            $st = $pdo->prepare("SELECT pp.*, rt.title AS room_type_title
                                 FROM rate_plan_prices pp
                                 LEFT JOIN room_types rt ON rt.id = pp.room_type_id
                                 WHERE pp.rate_plan_id = :id
                                 ORDER BY pp.room_type_id ASC, pp.valid_from ASC");
            $st->execute([':id' => $contractId]);
            $prices = $st->fetchAll(PDO::FETCH_ASSOC);

            /*
               Coverage gaps. A contract that does not price a date sends the
               agent to the public/rack rate silently - the Semper migration
               skipped 12 dead months and left exactly this. Surfacing gaps is
               the whole point: it is invisible lost margin otherwise.
            */
            $byType = [];
            foreach ($prices as $p) {
                if ((int)$p['status'] !== 1) continue;
                $byType[(int)$p['room_type_id']][] = $p;
            }
            foreach ($byType as $rt => $rows) {
                usort($rows, function($a,$b){ return strcmp($a['valid_from'], $b['valid_from']); });
                for ($i = 0; $i < count($rows) - 1; $i++) {
                    $end = strtotime($rows[$i]['valid_to']);
                    $nextStart = strtotime($rows[$i+1]['valid_from']);
                    $gapDays = (int)floor(($nextStart - $end) / 86400) - 1;
                    if ($gapDays > 0) {
                        $gaps[] = [
                            'room_type' => $roomTypeTitle[$rt] ?? ('Type #' . $rt),
                            'from' => date('Y-m-d', strtotime('+1 day', $end)),
                            'to'   => date('Y-m-d', strtotime('-1 day', $nextStart)),
                            'days' => $gapDays,
                        ];
                    }
                }
            }

            if ($hasAgentLink) {
                $st = $pdo->prepare("SELECT a.*, {$agentNameExpr} AS display_name
                                     FROM agents a WHERE a.rate_plan_id = :id
                                     ORDER BY display_name ASC LIMIT 500");
                $st->execute([':id' => $contractId]);
                $assignedAgents = $st->fetchAll(PDO::FETCH_ASSOC);

                $st = $pdo->query("SELECT a.id, {$agentNameExpr} AS display_name
                                   FROM agents a WHERE a.rate_plan_id IS NULL
                                   ORDER BY display_name ASC LIMIT 1000");
                $unassignedAgents = $st->fetchAll(PDO::FETCH_ASSOC);
            }
        }
    } catch (Throwable $e) { $errors[] = 'Could not load contract: ' . $e->getMessage(); }
}

/* Headline counts */
$totUnassigned = 0;
$totZeroSharing = 0;
try {
    if ($hasAgentLink) $totUnassigned = (int)$pdo->query("SELECT COUNT(*) FROM agents WHERE rate_plan_id IS NULL")->fetchColumn();
    $totZeroSharing = (int)$pdo->query("SELECT COUNT(*) FROM rate_plan_prices WHERE status = 1 AND sharing_rate <= 0")->fetchColumn();
} catch (Throwable $e) {}

require_once __DIR__ . '/../../includes/header.php';
?>

<div class="hero-band">
    <div class="row g-4 align-items-center">
        <div class="col-lg-8">
            <div class="page-eyebrow text-white-50"><i class="bi bi-file-earmark-ruled"></i> Rates</div>
            <div class="hero-title mt-2">Rate Contracts</div>
            <div class="hero-subtitle mt-2">
                A contract is priced once and shared by every agent on it. Public/rack rates live in
                <a href="rate_plans.php" class="text-white">Rate Plans</a>.
            </div>
        </div>
        <div class="col-lg-4 text-lg-end">
            <a href="rate_plans.php" class="btn btn-light"><i class="bi bi-tags me-2"></i>Rack Rates</a>
        </div>
    </div>
</div>

<?php foreach ($errors as $e): ?><div class="alert alert-danger"><?php echo h($e); ?></div><?php endforeach; ?>
<?php foreach ($notices as $n): ?><div class="alert alert-success"><?php echo h($n); ?></div><?php endforeach; ?>

<?php if ($totZeroSharing > 0): ?>
    <div class="alert alert-danger">
        <i class="bi bi-exclamation-octagon me-1"></i>
        <strong><?php echo (int)$totZeroSharing; ?> active season(s) have a sharing rate of 0.00.</strong>
        Sharing rate is charged <em>per adult</em>, so those seasons currently bill two adults <strong>0.00 per night</strong>.
    </div>
<?php endif; ?>
<?php if ($totUnassigned > 0): ?>
    <div class="alert alert-warning">
        <i class="bi bi-info-circle me-1"></i>
        <strong><?php echo (int)$totUnassigned; ?> agent(s) are on no contract</strong> and are being charged the public rate.
    </div>
<?php endif; ?>

<div class="row g-3">
    <!-- ================= CONTRACT LIST ================= -->
    <div class="col-lg-<?php echo $contract ? '4' : '12'; ?>">
        <div class="card panel-card">
            <div class="card-header d-flex justify-content-between align-items-center">
                <span><i class="bi bi-list-ul me-2"></i>Contracts (<?php echo count($contracts); ?>)</span>
                <a href="?contract_id=new" class="btn btn-sm btn-primary"><i class="bi bi-plus-lg"></i> New</a>
            </div>
            <div class="card-body">
                <form method="get" class="mb-2">
                    <input type="search" name="q" value="<?php echo h($search); ?>" class="form-control form-control-sm" placeholder="Search code or title...">
                </form>
                <div class="table-responsive" style="max-height:520px;overflow:auto;">
                    <table class="table table-sm table-hover align-middle mb-0">
                        <thead class="table-light"><tr><th>Contract</th><th>Meal</th><th class="text-end">Agents</th><th class="text-end">Seasons</th></tr></thead>
                        <tbody>
                        <?php if (!$contracts): ?>
                            <tr><td colspan="4" class="text-muted small p-3">No contracts yet.</td></tr>
                        <?php else: foreach ($contracts as $c): ?>
                            <tr class="<?php echo ((int)$c['id'] === $contractId) ? 'table-active' : ''; ?>">
                                <td>
                                    <a href="?contract_id=<?php echo (int)$c['id']; ?>" class="fw-semibold text-decoration-none">
                                        <?php echo h($c['title']); ?>
                                    </a>
                                    <div class="small text-muted">
                                        <?php echo h($c['code']); ?>
                                        <?php if ((int)$c['status'] !== 1): ?><span class="badge text-bg-secondary ms-1">Inactive</span><?php endif; ?>
                                        <?php if ($hasIsPublic && (int)($c['is_public'] ?? 0) === 1): ?><span class="badge text-bg-info ms-1">Public / Rack</span><?php endif; ?>
                                    </div>
                                </td>
                                <td><span class="badge text-bg-dark"><?php echo h($c['meal_plan']); ?></span></td>
                                <td class="text-end"><?php echo (int)$c['agent_count']; ?></td>
                                <td class="text-end">
                                    <?php echo (int)$c['price_rows']; ?>
                                    <?php if ((int)$c['price_rows'] === 0): ?>
                                        <i class="bi bi-exclamation-triangle text-warning" title="No prices - this contract cannot quote"></i>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; endif; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>

    <?php if ($contractId > 0 || ($_GET['contract_id'] ?? '') === 'new'): ?>
    <!-- ================= CONTRACT DETAIL ================= -->
    <div class="col-lg-8">
        <div class="card panel-card mb-3">
            <div class="card-header"><i class="bi bi-pencil-square me-2"></i><?php echo $contract ? 'Edit Contract' : 'New Contract'; ?></div>
            <div class="card-body">
                <form method="post" class="row g-2">
                    <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                    <input type="hidden" name="action" value="save_contract">
                    <input type="hidden" name="contract_id" value="<?php echo (int)($contract['id'] ?? 0); ?>">
                    <div class="col-md-3">
                        <label class="form-label small mb-1">Code *</label>
                        <input type="text" name="code" class="form-control form-control-sm" required
                               value="<?php echo h($contract['code'] ?? ''); ?>" placeholder="e.g. 1004">
                    </div>
                    <div class="col-md-5">
                        <label class="form-label small mb-1">Title *</label>
                        <input type="text" name="title" class="form-control form-control-sm" required
                               value="<?php echo h($contract['title'] ?? ''); ?>" placeholder="e.g. STO BB">
                    </div>
                    <div class="col-md-2">
                        <label class="form-label small mb-1">Meal Plan *</label>
                        <select name="meal_plan" class="form-select form-select-sm" required>
                            <?php foreach (roomz_meal_plans() as $mp => $lbl): ?>
                                <option value="<?php echo h($mp); ?>" <?php echo (string)($contract['meal_plan'] ?? 'BB') === $mp ? 'selected' : ''; ?>><?php echo h($mp); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="col-md-2 d-flex align-items-end">
                        <div class="form-check me-3">
                            <input class="form-check-input" type="checkbox" name="status" id="cStatus" value="1"
                                <?php echo (int)($contract['status'] ?? 1) === 1 ? 'checked' : ''; ?>>
                            <label class="form-check-label small" for="cStatus">Active</label>
                        </div>
                    </div>
                    <div class="col-md-9">
                        <label class="form-label small mb-1">Description</label>
                        <input type="text" name="description" class="form-control form-control-sm"
                               value="<?php echo h($contract['description'] ?? ''); ?>">
                    </div>
                    <?php if ($hasIsPublic): ?>
                    <div class="col-md-3 d-flex align-items-end">
                        <div class="form-check">
                            <input class="form-check-input" type="checkbox" name="is_public" id="cPublic" value="1"
                                <?php echo (int)($contract['is_public'] ?? 0) === 1 ? 'checked' : ''; ?>>
                            <label class="form-check-label small" for="cPublic">
                                Public / rack rate
                                <i class="bi bi-question-circle" title="Tick ONLY if walk-in guests should be quoted this rate. A negotiated contract must stay unticked, or it will be served to the public."></i>
                            </label>
                        </div>
                    </div>
                    <?php endif; ?>
                    <div class="col-12 text-end">
                        <button class="btn btn-sm btn-primary"><i class="bi bi-save me-1"></i>Save Contract</button>
                    </div>
                </form>
            </div>
        </div>

        <?php if ($contract): ?>
        <ul class="nav nav-tabs mb-3">
            <li class="nav-item"><a class="nav-link <?php echo $tab !== 'agents' ? 'active' : ''; ?>" href="?contract_id=<?php echo $contractId; ?>&tab=seasons">Seasons &amp; Prices (<?php echo count($prices); ?>)</a></li>
            <li class="nav-item"><a class="nav-link <?php echo $tab === 'agents' ? 'active' : ''; ?>" href="?contract_id=<?php echo $contractId; ?>&tab=agents">Agents (<?php echo count($assignedAgents); ?>)</a></li>
        </ul>

        <?php if ($tab !== 'agents'): ?>
            <?php if ($gaps): ?>
                <div class="alert alert-warning">
                    <strong><i class="bi bi-calendar-x me-1"></i>Coverage gaps.</strong>
                    On these dates this contract prices nothing, so its agents are silently charged the <em>public rate</em>:
                    <ul class="mb-0 mt-1 small">
                        <?php foreach ($gaps as $g): ?>
                            <li><?php echo h($g['room_type']); ?>: <?php echo h($g['from']); ?> to <?php echo h($g['to']); ?> (<?php echo (int)$g['days']; ?> days)</li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            <?php endif; ?>

            <div class="card panel-card mb-3">
                <div class="card-header"><i class="bi bi-plus-circle me-2"></i>Add a Season</div>
                <div class="card-body">
                    <form method="post" class="row g-2">
                        <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                        <input type="hidden" name="action" value="save_price">
                        <input type="hidden" name="contract_id" value="<?php echo $contractId; ?>">
                        <div class="col-md-4">
                            <label class="form-label small mb-1">Room Types * <span class="text-muted">(price all at once)</span></label>
                            <div class="border rounded p-2" style="max-height:110px;overflow:auto;">
                                <?php foreach ($roomTypes as $rt): ?>
                                    <div class="form-check form-check-inline">
                                        <input class="form-check-input" type="checkbox" name="room_type_ids[]"
                                               id="rt<?php echo (int)$rt['id']; ?>" value="<?php echo (int)$rt['id']; ?>">
                                        <label class="form-check-label small" for="rt<?php echo (int)$rt['id']; ?>"><?php echo h($rt['title']); ?></label>
                                    </div>
                                <?php endforeach; ?>
                            </div>
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Valid From *</label>
                            <input type="date" name="valid_from" class="form-control form-control-sm" required>
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Valid To *</label>
                            <input type="date" name="valid_to" class="form-control form-control-sm" required>
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Sharing (per adult) *</label>
                            <input type="number" step="0.01" min="0" name="sharing_rate" class="form-control form-control-sm text-end" required>
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Single Rate</label>
                            <input type="number" step="0.01" min="0" name="single_rate" class="form-control form-control-sm text-end" value="0.00">
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Single Supplement</label>
                            <input type="number" step="0.01" min="0" name="single_supplement" class="form-control form-control-sm text-end" value="0.00">
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Child %</label>
                            <input type="number" step="0.01" min="0" name="child_rate_percent" class="form-control form-control-sm text-end" value="50.00">
                        </div>
                        <div class="col-md-2">
                            <label class="form-label small mb-1">Currency</label>
                            <input type="text" name="currency" class="form-control form-control-sm" value="USD" maxlength="10">
                        </div>
                        <div class="col-md-2 d-flex align-items-end">
                            <div class="form-check">
                                <input class="form-check-input" type="checkbox" name="status" id="pStatus" value="1" checked>
                                <label class="form-check-label small" for="pStatus">Active</label>
                            </div>
                        </div>
                        <div class="col-md-4 text-end d-flex align-items-end justify-content-end">
                            <button class="btn btn-sm btn-primary"><i class="bi bi-plus-lg me-1"></i>Add Season</button>
                        </div>
                        <div class="col-12">
                            <div class="form-text">
                                <strong>Sharing rate is per adult.</strong> Two adults pay 2 &times; sharing.
                                Single occupancy uses the Single Rate when set, otherwise Sharing + Supplement &mdash; never both.
                            </div>
                        </div>
                    </form>
                </div>
            </div>

            <div class="card panel-card">
                <div class="card-header"><i class="bi bi-calendar3 me-2"></i>Seasons</div>
                <div class="card-body p-0">
                    <div class="table-responsive">
                        <table class="table table-sm align-middle mb-0">
                            <thead class="table-light">
                                <tr><th>Room Type</th><th>From</th><th>To</th><th class="text-end">Sharing</th>
                                    <th class="text-end">Single</th><th class="text-end">Suppl.</th><th class="text-end">Child %</th>
                                    <th class="text-end">2 adults</th><th>Status</th><th></th></tr>
                            </thead>
                            <tbody>
                            <?php if (!$prices): ?>
                                <tr><td colspan="10" class="text-muted small p-3">No seasons yet &mdash; this contract cannot quote a rate.</td></tr>
                            <?php else: foreach ($prices as $p): ?>
                                <?php $zeroShare = ((int)$p['status'] === 1 && (float)$p['sharing_rate'] <= 0); ?>
                                <tr class="<?php echo $zeroShare ? 'table-danger' : ((int)$p['status'] !== 1 ? 'text-muted' : ''); ?>">
                                    <td class="small"><?php echo h($p['room_type_title'] ?? ('#' . $p['room_type_id'])); ?></td>
                                    <td class="small"><?php echo h($p['valid_from']); ?></td>
                                    <td class="small"><?php echo h($p['valid_to']); ?></td>
                                    <td class="text-end"><?php echo money_fmt($p['sharing_rate']); ?></td>
                                    <td class="text-end"><?php echo money_fmt($p['single_rate']); ?></td>
                                    <td class="text-end"><?php echo money_fmt($p['single_supplement']); ?></td>
                                    <td class="text-end"><?php echo money_fmt($p['child_rate_percent']); ?></td>
                                    <td class="text-end fw-semibold <?php echo $zeroShare ? 'text-danger' : ''; ?>">
                                        <?php echo money_fmt(2 * (float)$p['sharing_rate']); ?>
                                        <?php if ($zeroShare): ?><i class="bi bi-exclamation-octagon" title="Two adults would be billed 0.00 per night"></i><?php endif; ?>
                                    </td>
                                    <td><?php echo (int)$p['status'] === 1 ? '<span class="badge text-bg-success">Active</span>' : '<span class="badge text-bg-secondary">Inactive</span>'; ?></td>
                                    <td class="text-end text-nowrap">
                                        <button type="button" class="btn btn-sm btn-outline-secondary rc-edit-price"
                                                data-price='<?php echo h(json_encode($p)); ?>'><i class="bi bi-pencil"></i></button>
                                        <form method="post" class="d-inline" onsubmit="return confirm('Delete this season? Agents on this contract will fall back to the public rate for these dates.');">
                                            <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                                            <input type="hidden" name="action" value="delete_price">
                                            <input type="hidden" name="price_id" value="<?php echo (int)$p['id']; ?>">
                                            <input type="hidden" name="contract_id" value="<?php echo $contractId; ?>">
                                            <button class="btn btn-sm btn-outline-danger"><i class="bi bi-trash"></i></button>
                                        </form>
                                    </td>
                                </tr>
                            <?php endforeach; endif; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>

        <?php else: /* ---------------- AGENTS TAB ---------------- */ ?>

            <?php if (!$hasAgentLink): ?>
                <div class="alert alert-warning">The <code>agents.rate_plan_id</code> column does not exist. Run <code>01_migrate.sql</code>.</div>
            <?php else: ?>
            <div class="card panel-card mb-3">
                <div class="card-header"><i class="bi bi-person-plus me-2"></i>Assign Agents to <?php echo h($contract['title']); ?></div>
                <div class="card-body">
                    <form method="post">
                        <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                        <input type="hidden" name="action" value="assign_agents">
                        <input type="hidden" name="contract_id" value="<?php echo $contractId; ?>">
                        <div class="mb-2">
                            <input type="search" id="rcAgentSearch" class="form-control form-control-sm" placeholder="Filter unassigned agents...">
                        </div>
                        <div class="border rounded p-2 mb-2" style="max-height:260px;overflow:auto;">
                            <?php if (!$unassignedAgents): ?>
                                <div class="text-muted small">Every agent is already on a contract.</div>
                            <?php else: foreach ($unassignedAgents as $ua): ?>
                                <div class="form-check rc-agent-row">
                                    <input class="form-check-input" type="checkbox" name="agent_ids[]"
                                           id="ua<?php echo (int)$ua['id']; ?>" value="<?php echo (int)$ua['id']; ?>">
                                    <label class="form-check-label small" for="ua<?php echo (int)$ua['id']; ?>">
                                        <?php echo h($ua['display_name']); ?> <span class="text-muted">#<?php echo (int)$ua['id']; ?></span>
                                    </label>
                                </div>
                            <?php endforeach; endif; ?>
                        </div>
                        <?php if ($unassignedAgents): ?>
                            <button class="btn btn-sm btn-primary"><i class="bi bi-check2 me-1"></i>Assign Selected</button>
                            <span class="small text-muted ms-2">Only agents currently on no contract are listed.</span>
                        <?php endif; ?>
                    </form>
                </div>
            </div>

            <div class="card panel-card">
                <div class="card-header"><i class="bi bi-people me-2"></i>Agents on this Contract (<?php echo count($assignedAgents); ?>)</div>
                <div class="card-body p-0">
                    <div class="table-responsive" style="max-height:420px;overflow:auto;">
                        <table class="table table-sm align-middle mb-0">
                            <thead class="table-light"><tr><th>Agent</th><th>ID</th><th></th></tr></thead>
                            <tbody>
                            <?php if (!$assignedAgents): ?>
                                <tr><td colspan="3" class="text-muted small p-3">No agents on this contract.</td></tr>
                            <?php else: foreach ($assignedAgents as $aa): ?>
                                <tr>
                                    <td class="small"><?php echo h($aa['display_name']); ?></td>
                                    <td class="small text-muted">#<?php echo (int)$aa['id']; ?></td>
                                    <td class="text-end">
                                        <form method="post" class="d-inline" onsubmit="return confirm('Remove this agent from the contract? They will be charged the public rate.');">
                                            <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
                                            <input type="hidden" name="action" value="unassign_agent">
                                            <input type="hidden" name="agent_id" value="<?php echo (int)$aa['id']; ?>">
                                            <input type="hidden" name="contract_id" value="<?php echo $contractId; ?>">
                                            <button class="btn btn-sm btn-outline-danger"><i class="bi bi-x-lg"></i></button>
                                        </form>
                                    </td>
                                </tr>
                            <?php endforeach; endif; ?>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
            <?php endif; ?>

        <?php endif; ?>
        <?php endif; ?>
    </div>
    <?php endif; ?>
</div>

<!-- ================= EDIT SEASON MODAL ================= -->
<div class="modal fade" id="rcEditPriceModal" tabindex="-1">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <form method="post">
        <?php if (function_exists('csrf_field')) echo csrf_field(); ?>
        <input type="hidden" name="action" value="save_price">
        <input type="hidden" name="price_id" id="epPriceId">
        <input type="hidden" name="contract_id" value="<?php echo $contractId; ?>">
        <div class="modal-header"><h5 class="modal-title">Edit Season</h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal"></button></div>
        <div class="modal-body">
          <div class="row g-2">
            <div class="col-md-4">
              <label class="form-label small mb-1">Room Type</label>
              <select name="room_type_ids[]" id="epRoomType" class="form-select form-select-sm" required>
                <?php foreach ($roomTypes as $rt): ?>
                  <option value="<?php echo (int)$rt['id']; ?>"><?php echo h($rt['title']); ?></option>
                <?php endforeach; ?>
              </select>
            </div>
            <div class="col-md-4"><label class="form-label small mb-1">Valid From</label>
              <input type="date" name="valid_from" id="epFrom" class="form-control form-control-sm" required></div>
            <div class="col-md-4"><label class="form-label small mb-1">Valid To</label>
              <input type="date" name="valid_to" id="epTo" class="form-control form-control-sm" required></div>
            <div class="col-md-3"><label class="form-label small mb-1">Sharing (per adult)</label>
              <input type="number" step="0.01" min="0" name="sharing_rate" id="epSharing" class="form-control form-control-sm text-end" required></div>
            <div class="col-md-3"><label class="form-label small mb-1">Single Rate</label>
              <input type="number" step="0.01" min="0" name="single_rate" id="epSingle" class="form-control form-control-sm text-end"></div>
            <div class="col-md-3"><label class="form-label small mb-1">Single Supplement</label>
              <input type="number" step="0.01" min="0" name="single_supplement" id="epSuppl" class="form-control form-control-sm text-end"></div>
            <div class="col-md-3"><label class="form-label small mb-1">Child %</label>
              <input type="number" step="0.01" min="0" name="child_rate_percent" id="epChild" class="form-control form-control-sm text-end"></div>
            <div class="col-md-3"><label class="form-label small mb-1">Currency</label>
              <input type="text" name="currency" id="epCurrency" class="form-control form-control-sm" maxlength="10"></div>
            <div class="col-md-3 d-flex align-items-end">
              <div class="form-check">
                <input class="form-check-input" type="checkbox" name="status" id="epStatus" value="1">
                <label class="form-check-label small" for="epStatus">Active</label>
              </div>
            </div>
            <div class="col-md-6 d-flex align-items-end">
              <div class="small text-muted">Two adults will pay <strong id="epCouple">0.00</strong> per night.</div>
            </div>
          </div>
        </div>
        <div class="modal-footer">
          <button type="button" class="btn btn-outline-secondary" data-bs-dismiss="modal">Cancel</button>
          <button class="btn btn-primary">Save Season</button>
        </div>
      </form>
    </div>
  </div>
</div>

<script>
document.addEventListener('DOMContentLoaded', function () {
    // Populate the edit modal from the clicked row.
    var modalEl = document.getElementById('rcEditPriceModal');
    function couple() {
        var s = parseFloat(document.getElementById('epSharing').value || '0') || 0;
        document.getElementById('epCouple').textContent = (2 * s).toFixed(2);
    }
    document.querySelectorAll('.rc-edit-price').forEach(function (btn) {
        btn.addEventListener('click', function () {
            var p = {};
            try { p = JSON.parse(btn.getAttribute('data-price') || '{}'); } catch (e) { p = {}; }
            document.getElementById('epPriceId').value = p.id || '';
            var rtSel = document.getElementById('epRoomType');
            if (rtSel) rtSel.value = p.room_type_id || '';
            document.getElementById('epFrom').value = p.valid_from || '';
            document.getElementById('epTo').value = p.valid_to || '';
            document.getElementById('epSharing').value = p.sharing_rate || '0';
            document.getElementById('epSingle').value = p.single_rate || '0';
            document.getElementById('epSuppl').value = p.single_supplement || '0';
            document.getElementById('epChild').value = p.child_rate_percent || '50';
            document.getElementById('epCurrency').value = p.currency || 'USD';
            document.getElementById('epStatus').checked = (parseInt(p.status, 10) === 1);
            couple();
            if (modalEl && window.bootstrap) new bootstrap.Modal(modalEl).show();
        });
    });
    var sh = document.getElementById('epSharing');
    if (sh) sh.addEventListener('input', couple);

    // Filter the unassigned agent list client-side.
    var search = document.getElementById('rcAgentSearch');
    if (search) {
        search.addEventListener('input', function () {
            var q = search.value.toLowerCase();
            document.querySelectorAll('.rc-agent-row').forEach(function (row) {
                var label = row.querySelector('label');
                var txt = label ? label.textContent.toLowerCase() : '';
                row.style.display = (q === '' || txt.indexOf(q) !== -1) ? '' : 'none';
            });
        });
    }
});
</script>

<style>
.hero-band{padding:10px 14px!important;margin-bottom:8px!important}
.hero-band .btn{padding:5px 9px!important;font-size:.78rem!important;border-radius:8px!important}
.panel-card .card-header{padding:9px 12px!important}
</style>

<?php require_once __DIR__ . '/../../includes/footer.php'; ?>
