<?php
/**
 * Slice 8S-9 smoke — proves the Services checklist auto-ticks as ServiceContracts data
 * lands. Snapshots the count of complete SVC_* items after each write.
 *
 * Expected trajectory:
 *   after saveHeader (with all rate/policy/cadence fields set)  → 4 items auto-tick
 *                                       (SPARE_POLICY, INVOICING_CADENCE, CALLOUT_PAYMENT, PRICING_MODEL)
 *   after saveSite                                              → +1 (SITES_LIST)      = 5
 *   after saveAsset (matches an active service_pack)            → +2 (EQUIPMENT_LIST, SERVICE_PACK) = 7
 *   after saveSla                                               → +1 (CALLOUT_CATEGORY_SLA) = 8
 *   after generateSchedule                                      → +1 (MAINTENANCE_STRUCTURE) = 9
 *   SVC_PART_REPLACEMENT stays manual                           = 9 of 10 auto-ticked
 */
define('DS', DIRECTORY_SEPARATOR);
define('ROOT', dirname(__DIR__));
if (!defined('DB_HOST'))     define('DB_HOST', 'localhost');
if (!defined('DB_NAME'))     define('DB_NAME', 'rookpmgt_rsflow');
if (!defined('DB_USER'))     define('DB_USER', 'root');
if (!defined('DB_PASSWORD')) define('DB_PASSWORD', '');
if (!defined('DB_PASS'))     define('DB_PASS', '');
require_once ROOT . '/core/DB.php';
require_once ROOT . '/core/Model.php';
require_once ROOT . '/app/models/AssetTypes.php';
require_once ROOT . '/app/models/SpareParts.php';
require_once ROOT . '/app/models/ServicePacks.php';
require_once ROOT . '/app/models/PmTemplates.php';
require_once ROOT . '/app/models/Projects.php';
require_once ROOT . '/app/models/ServiceContracts.php';

$pdo = new PDO('mysql:host=localhost;dbname=rookpmgt_rsflow;charset=utf8mb4', 'root', '');
function h(string $t): void { echo "\n==== $t ====\n"; }
function p(string $t): void { echo "  $t\n"; }
function ok(bool $c, string $m): void { echo ($c ? "  ✓ " : "  ✗ ") . $m . PHP_EOL; }

/* ── Wipe prior smoke data ─────────────────────────────────────────── */
$pdo->exec("DELETE FROM service_contract_pm_schedule WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='S9-SMOKE-CUST')");
$pdo->exec("DELETE FROM service_contract_slas   WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='S9-SMOKE-CUST')");
$pdo->exec("DELETE FROM service_contract_assets WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='S9-SMOKE-CUST')");
$pdo->exec("DELETE FROM service_contract_sites  WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='S9-SMOKE-CUST')");
$pdo->exec("DELETE FROM service_contracts WHERE customer_name='S9-SMOKE-CUST'");
$pdo->exec("DELETE FROM crm_project_checklist_items WHERE project_id IN (SELECT c0d FROM c_projects WHERE project_name='S9 Smoke Project')");
$pdo->exec("DELETE FROM crm_project_onboarding WHERE project_id IN (SELECT c0d FROM c_projects WHERE project_name='S9 Smoke Project')");
$pdo->exec("DELETE FROM c_projects WHERE project_name='S9 Smoke Project'");
$pdo->exec("DELETE FROM service_pack_items WHERE pack_id IN (SELECT c0d FROM service_packs WHERE code='S9-SMOKE-PACK')");
$pdo->exec("DELETE FROM service_packs WHERE code='S9-SMOKE-PACK'");
$pdo->exec("DELETE FROM pm_template_items WHERE template_id IN (SELECT c0d FROM pm_templates WHERE code='S9-SMOKE-TPL')");
$pdo->exec("DELETE FROM pm_templates WHERE code='S9-SMOKE-TPL'");
$pdo->exec("DELETE FROM spare_parts WHERE sku='S9-SMOKE-OIL'");
$pdo->exec("DELETE FROM customers WHERE fname='S9-SMOKE-CUST'");

/* ── Setup: customer + services project ────────────────────────────── */
$pdo->exec("INSERT INTO customers (customer_no, customer_code, fname, lname, status, created_on)
    VALUES ('S9-C1','S9','S9-SMOKE-CUST','Ltd','ACTIVE',NOW())");
$custId = (int)$pdo->lastInsertId();

$daj = 'Test smoke run — proves the Services checklist auto-ticks against live service_contract data.';
$projRes = (new Projects())->create([
    'project_name'               => 'S9 Smoke Project',
    'project_type'               => 'services',
    'project_customer_id'        => $custId,
    'origin'                     => 'DIRECT_AWARD',
    'direct_award_justification' => $daj,
    'project_start_date'         => date('Y-m-d'),
    'contract_value'             => 10000000,
    'currency'                   => 'TZS',
], 0, 'smoke');
$projId = (int)$projRes['id'];
p("Project id=$projId · type=services · 19 checklist items seeded");

/* Baseline: 0 SVC_* items ticked */
function svcDone(PDO $pdo, int $pid): int {
    return (int)$pdo->query("SELECT COUNT(*) FROM crm_project_checklist_items WHERE project_id=$pid AND checklist_key LIKE 'SVC_%' AND is_complete=1")->fetchColumn();
}
function whichSvc(PDO $pdo, int $pid): array {
    $r = $pdo->query("SELECT checklist_key FROM crm_project_checklist_items WHERE project_id=$pid AND checklist_key LIKE 'SVC_%' AND is_complete=1 ORDER BY checklist_key")->fetchAll(PDO::FETCH_COLUMN);
    return $r;
}
h('Baseline (empty project, no contract)');
$before = svcDone($pdo, $projId);
p("SVC_* ticked: $before / 10");
ok($before === 0, "0 items ticked before any data lands");

/* ── Seed the master data the auto-tick needs ─────────────────────── */
$types = (new AssetTypes())->all(true);
$genId = 0; foreach ($types as $t) if ($t['code']==='GEN') { $genId=(int)$t['c0d']; break; }
$partId = (new SpareParts())->save(['sku'=>'S9-SMOKE-OIL','name'=>'15W40 5L','uom'=>'L','asset_type_id'=>$genId,'unit_cost'=>25000,'default_markup_pct'=>25,'is_active'=>1], 0);
$packId = (new ServicePacks())->saveHeader(['code'=>'S9-SMOKE-PACK','name'=>'Gen 60-100kVA 250hr','asset_type_id'=>$genId,'size_min'=>60,'size_max'=>100,'size_unit'=>'kVA','is_active'=>1], 0);
$tid = (new PmTemplates())->saveHeader(['code'=>'S9-SMOKE-TPL','name'=>'Gen quarterly','asset_type_id'=>$genId,'scope'=>'ASSET','cadence_type'=>'MONTHS','cadence_value'=>3,'is_active'=>1], 0);
p("Seeded: part id=$partId · pack id=$packId · template id=$tid");

/* ── Step A — saveHeader with all rate/policy fields ─────────────── */
h('A · saveHeader with spare_policy + invoice_cadence + callout fields + pricing fields');
$sc = new ServiceContracts();
$cid = $sc->saveHeader([
    'project_id'              => $projId, 'customer_name' => 'S9-SMOKE-CUST', 'customer_id' => $custId,
    'contract_value'          => 10000000, 'currency' => 'TZS', 'monthly_retainer' => 500000,
    'spare_policy'            => 'COMPANY',
    'invoice_cadence'         => 'CONSUMPTION',
    'payment_terms_days'      => 30,
    'labour_rate_per_hr'      => 50000,
    'callout_fee'             => 150000,
    'emergency_multiplier'    => 2,
    'parts_markup_pct'        => 25,
    'mileage_rate_per_km'     => 1500,
    'free_callouts_per_month' => 2,
], 0, 'smoke');
$after = svcDone($pdo, $projId);
$which = whichSvc($pdo, $projId);
p("Contract id=$cid");
p("SVC_* ticked: $after / 10 — " . implode(', ', $which));
ok(in_array('SVC_SPARE_POLICY', $which),      "SPARE_POLICY auto-ticked");
ok(in_array('SVC_INVOICING_CADENCE', $which), "INVOICING_CADENCE auto-ticked");
ok(in_array('SVC_CALLOUT_PAYMENT', $which),   "CALLOUT_PAYMENT auto-ticked");
ok(in_array('SVC_PRICING_MODEL', $which),     "PRICING_MODEL auto-ticked");

/* ── Step B — saveSite ─────────────────────────────────────────────── */
h('B · saveSite');
$sid = $sc->saveSite(['contract_id'=>$cid,'name'=>'Kariakoo Branch','is_active'=>1]);
$which = whichSvc($pdo, $projId);
p("Site id=$sid — SVC_* ticked: " . count($which) . " · " . implode(', ', $which));
ok(in_array('SVC_SITES_LIST', $which), "SITES_LIST auto-ticked");

/* ── Step C — saveAsset (kVA in pack range 60-100) ─────────────────── */
h('C · saveAsset (75 kVA — matches active pack 60-100 kVA)');
$aid = $sc->saveAsset(['contract_id'=>$cid,'site_id'=>$sid,'asset_type_id'=>$genId,'asset_no'=>'GEN-S9-01','size_value'=>75,'size_unit'=>'kVA','is_active'=>1]);
$which = whichSvc($pdo, $projId);
p("Asset id=$aid — SVC_* ticked: " . count($which) . " · " . implode(', ', $which));
ok(in_array('SVC_EQUIPMENT_LIST', $which), "EQUIPMENT_LIST auto-ticked");
ok(in_array('SVC_SERVICE_PACK', $which),   "SERVICE_PACK auto-ticked (matched by size range)");

/* ── Step D — saveSla ──────────────────────────────────────────────── */
h('D · saveSla (Emergency override)');
$emergId = (int)$pdo->query("SELECT c0d FROM callout_categories WHERE code='EMERGENCY'")->fetchColumn();
$sc->saveSla(['contract_id'=>$cid,'category_id'=>$emergId,'sla_response_hrs'=>2,'sla_restoration_hrs'=>4,'penalty_pct_per_hr'=>1.5]);
$which = whichSvc($pdo, $projId);
p("SVC_* ticked: " . count($which) . " · " . implode(', ', $which));
ok(in_array('SVC_CALLOUT_CATEGORY_SLA', $which), "CALLOUT_CATEGORY_SLA auto-ticked");

/* ── Step E — generateSchedule ─────────────────────────────────────── */
h('E · generateSchedule (needs template that matches asset_type=GEN + MONTHS cadence)');
// Must activate contract first (guarded)
$sc->activate($cid, 0);
$sc->generateSchedule($cid);
$which = whichSvc($pdo, $projId);
p("SVC_* ticked: " . count($which) . " · " . implode(', ', $which));
ok(in_array('SVC_MAINTENANCE_STRUCTURE', $which), "MAINTENANCE_STRUCTURE auto-ticked");

/* ── Final state ───────────────────────────────────────────────────── */
h('Final state');
$after = svcDone($pdo, $projId);
p("SVC_* auto-ticked: $after / 10 (expected 9 — SVC_PART_REPLACEMENT stays manual)");
ok($after === 9, "9 of 10 auto-ticked correctly");
$manual = $pdo->query("SELECT checklist_key FROM crm_project_checklist_items WHERE project_id=$projId AND checklist_key LIKE 'SVC_%' AND is_complete=0")->fetch(PDO::FETCH_COLUMN);
ok($manual === 'SVC_PART_REPLACEMENT', "Manual-only item is SVC_PART_REPLACEMENT (got: $manual)");

/* ── Reverse: prove flip-off works when data goes away ─────────────── */
h('Reverse · delete the asset — EQUIPMENT_LIST and SERVICE_PACK should flip off');
$sc->deleteAsset($aid);
$which = whichSvc($pdo, $projId);
p("SVC_* ticked: " . count($which) . " · " . implode(', ', $which));
ok(!in_array('SVC_EQUIPMENT_LIST', $which), "EQUIPMENT_LIST correctly un-ticked");
ok(!in_array('SVC_SERVICE_PACK', $which),   "SERVICE_PACK correctly un-ticked");
ok(!in_array('SVC_MAINTENANCE_STRUCTURE', $which), "MAINTENANCE_STRUCTURE also un-ticked (schedule was cleared with asset)");

/* ── Cleanup ──────────────────────────────────────────────────────── */
h('Cleanup');
$pdo->exec("DELETE FROM service_contract_pm_schedule WHERE contract_id=$cid");
$pdo->exec("DELETE FROM service_contract_slas WHERE contract_id=$cid");
$pdo->exec("DELETE FROM service_contract_assets WHERE contract_id=$cid");
$pdo->exec("DELETE FROM service_contract_sites WHERE contract_id=$cid");
$pdo->exec("DELETE FROM service_contracts WHERE c0d=$cid");
$pdo->exec("DELETE FROM crm_project_checklist_items WHERE project_id=$projId");
$pdo->exec("DELETE FROM crm_project_onboarding WHERE project_id=$projId");
$pdo->exec("DELETE FROM c_projects WHERE c0d=$projId");
$pdo->exec("DELETE FROM customers WHERE c0d=$custId");
$pdo->exec("DELETE FROM service_packs WHERE c0d=$packId");
$pdo->exec("DELETE FROM pm_template_items WHERE template_id=$tid");
$pdo->exec("DELETE FROM pm_templates WHERE c0d=$tid");
$pdo->exec("DELETE FROM spare_parts WHERE c0d=$partId");
p("All test data removed");
echo PHP_EOL;
