<?php
/**
 * Services E2E — walks a Service tender from CRM through project creation, checklist,
 * approval chain, and into an activated ServiceContract.
 *
 * Steps:
 *  1. Ensure a test customer exists
 *  2. Create a services project via Projects::create (DIRECT_AWARD to skip tender plumbing)
 *  3. Verify the 19 checklist items (9 common + 10 services-specific) got seeded
 *  4. Mark all checklist items complete
 *  5. Simulate the chain approval by flipping crm_status to APPROVED
 *  6. Create a ServiceContract linked to the project
 *  7. Add a site + asset, activate the contract
 *  8. Generate the PM schedule
 *  9. Print a summary of what was set up
 * 10. Cleanup
 */
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/Projects.php';
require_once ROOT . '/app/models/ServiceContracts.php';
require_once ROOT . '/app/models/PmTemplates.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 $cond, string $msg): void { echo ($cond ? "  \xE2\x9C\x93 " : "  \xE2\x9C\x97 ") . $msg . PHP_EOL; }

/* ── Cleanup previous run ─────────────────────────────────────────── */
$pdo->exec("DELETE FROM service_contract_pm_schedule WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='CRM-E2E-Vodacom')");
$pdo->exec("DELETE FROM service_contract_assets WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='CRM-E2E-Vodacom')");
$pdo->exec("DELETE FROM service_contract_sites  WHERE contract_id IN (SELECT c0d FROM service_contracts WHERE customer_name='CRM-E2E-Vodacom')");
$pdo->exec("DELETE FROM service_contracts WHERE customer_name='CRM-E2E-Vodacom'");
$pdo->exec("DELETE FROM crm_project_checklist_items WHERE project_id IN (SELECT c0d FROM c_projects WHERE project_name = 'CRM E2E · Tower PM Contract')");
$pdo->exec("DELETE FROM crm_project_onboarding WHERE project_id IN (SELECT c0d FROM c_projects WHERE project_name = 'CRM E2E · Tower PM Contract')");
$pdo->exec("DELETE FROM c_projects WHERE project_name = 'CRM E2E · Tower PM Contract'");
$pdo->exec("DELETE FROM customers WHERE fname = 'CRM-E2E-Vodacom' AND lname = 'Tanzania'");
$pdo->exec("DELETE FROM pm_template_items WHERE template_id IN (SELECT c0d FROM pm_templates WHERE code = 'GEN_QUARTERLY_E2E')");
$pdo->exec("DELETE FROM pm_templates WHERE code = 'GEN_QUARTERLY_E2E'");

/* ── 1. Ensure test customer ──────────────────────────────────────── */
h('1. Test customer');
$pdo->exec("INSERT INTO customers (customer_no, customer_code, fname, lname, phone_1, physical_address, city, country, customer_tin, customer_vrn, status, created_on)
    VALUES ('E2E-C001','E2E','CRM-E2E-Vodacom','Tanzania','+255-22-000-0000','Msasani, Dar','Dar es Salaam','Tanzania','123-456-789','40-123-456-VAT','ACTIVE',NOW())");
$custId = (int)$pdo->lastInsertId();
p("Customer id=$custId · CRM-E2E-Vodacom Tanzania · TIN + VRN captured");

/* ── 2. Create Services project via Projects::create ──────────────── */
h('2. Create Service project (DIRECT_AWARD origin)');
$daj = 'Vodacom TZ awarded a 3-year tower generator PM contract via a private RFP process. '
     . 'We were the lowest bidder amongst 4 shortlisted vendors. See email trail 2026-08-15 from '
     . 'their Head of Facilities. Terms: 45 sites, quarterly PM, callouts on-demand, 5% penalty per hour on breach.';
$projRes = (new Projects())->create([
    'project_name'               => 'CRM E2E · Tower PM Contract',
    'project_type'               => 'services',
    'project_customer_id'        => $custId,
    'origin'                     => 'DIRECT_AWARD',
    'direct_award_justification' => $daj,
    'project_start_date'         => date('Y-m-d'),
    'project_end_date'           => date('Y-m-d', strtotime('+3 years')),
    'contract_value'             => 540000000,   // 45 sites × 4M/yr × 3 yrs
    'currency'                   => 'TZS',
    'default_margin_pct'         => 30,
    'region'                     => 'Dar',
], 0, 'CRM Test');

if (empty($projRes['ok'])) { echo "\nFATAL: project create failed — {$projRes['msg']}\n"; exit(1); }
$projId = (int)$projRes['id'];
p("Project id=$projId · " . $projRes['msg']);

/* ── 3. Verify the extended Services checklist got seeded ─────────── */
h('3. Verify Services checklist seeded');
$items = $pdo->query("SELECT checklist_key, checklist_label FROM crm_project_checklist_items WHERE project_id=$projId ORDER BY c0d")->fetchAll(PDO::FETCH_ASSOC);
p("Total items: " . count($items));
$commonKeys   = ['CONTRACT_RECEIVED','TENDER_AWARD_LETTER','INSURANCE_CERT','BANKERS_GUARANTEE','KICKOFF_MEETING','PC_ASSIGNED','PM_ASSIGNED','HSE_PLAN','MOBILIZATION_PLAN'];
$servicesKeys = ['SVC_SITES_LIST','SVC_EQUIPMENT_LIST','SVC_MAINTENANCE_STRUCTURE','SVC_CALLOUT_CATEGORY_SLA','SVC_SPARE_POLICY','SVC_SERVICE_PACK','SVC_INVOICING_CADENCE','SVC_CALLOUT_PAYMENT','SVC_PRICING_MODEL','SVC_PART_REPLACEMENT'];
$actualKeys   = array_column($items, 'checklist_key');

ok(count($items) === 19, "Expected 19 items (9 common + 10 services), got " . count($items));
foreach ($commonKeys as $k)   ok(in_array($k, $actualKeys, true), "Common item present: $k");
foreach ($servicesKeys as $k) ok(in_array($k, $actualKeys, true), "Services item present: $k");

echo PHP_EOL . "  --- Services-specific items ---" . PHP_EOL;
foreach ($items as $it) {
    if (str_starts_with($it['checklist_key'], 'SVC_')) {
        p("  • " . $it['checklist_key'] . " → " . $it['checklist_label']);
    }
}

/* ── 4. Complete all checklist items ───────────────────────────────── */
h('4. CRM completes all 19 checklist items');
$pdo->exec("UPDATE crm_project_checklist_items SET is_complete=1, completed_on=NOW(), completed_by=0 WHERE project_id=$projId");
$done = (int)$pdo->query("SELECT SUM(is_complete) FROM crm_project_checklist_items WHERE project_id=$projId")->fetchColumn();
ok($done === 19, "All 19 items completed (got $done)");

/* ── 5. Simulate the chain approval (PC review → Exec approve terminal) ─── */
h('5. Simulate CRM_PROJECT_ONBOARDING chain approval');
p("(Real flow: OnboardingController::submitAj → ApprovalChain::submit → PC + Exec approve via FinChains/myQueue)");
p("For this smoke, we simulate the terminal-approval callback that flips crm_status:");
$pdo->exec("UPDATE c_projects SET crm_status='APPROVED', edited_by=0 WHERE c0d=$projId");
$crmStatus = $pdo->query("SELECT crm_status FROM c_projects WHERE c0d=$projId")->fetchColumn();
ok($crmStatus === 'APPROVED', "c_projects.crm_status=$crmStatus");

/* ── 6. Create a Service Contract linked to project ────────────────── */
h('6. Create Service Contract (with Vodacom-style terms)');
$sc  = new ServiceContracts();
$cid = $sc->saveHeader([
    'project_id'              => $projId,
    'customer_name'           => 'CRM-E2E-Vodacom Tanzania',
    'customer_id'             => $custId,
    'start_date'              => date('Y-m-d'),
    'end_date'                => date('Y-m-d', strtotime('+3 years')),
    'contract_value'          => 540000000,
    'currency'                => 'TZS',
    'monthly_retainer'        => 15000000,   // 45 sites × ~330k/site
    'spare_policy'            => 'CLIENT',    // Vodacom supplies spares
    'invoice_cadence'         => 'MONTHLY_RETAINER',
    'payment_terms_days'      => 45,
    'labour_rate_per_hr'      => 55000,
    'callout_fee'             => 250000,
    'emergency_multiplier'    => 2.5,
    'parts_markup_pct'        => 20,
    'mileage_rate_per_km'     => 2000,
    'free_callouts_per_month' => 45,          // one free per site per month
    'report_cadence'          => 'MONTHLY',
    'notes'                   => 'Tower gen PM · 3-year contract · quarterly PM cadence · 4h emergency SLA',
], 0, 'CRM Test');
p("Contract id=$cid · created in DRAFT status");

/* ── 7. Add a sample site + 2 assets ──────────────────────────────── */
h('7. Add sample site + 2 gensets');
$types = (new AssetTypes())->all(true);
$genId = 0; foreach ($types as $t) if ($t['code']==='GEN') { $genId=(int)$t['c0d']; break; }
$sid = $sc->saveSite([
    'contract_id'         => $cid,
    'site_code'           => 'BTS-DAR-001',
    'name'                => 'Vodacom BTS · Kariakoo',
    'physical_address'    => 'Congo St, Kariakoo, Dar es Salaam',
    'region'              => 'Dar',
    'district'            => 'Ilala',
    'gps_lat'             => -6.8123,
    'gps_lng'             => 39.2789,
    'site_contact_name'   => 'Salim (site guard)',
    'site_contact_phone'  => '+255-71-234-5678',
    'access_notes'        => 'Gate opens 06:00-22:00. Access card required from Vodacom NOC.',
    'is_active'           => 1,
]);
p("Site id=$sid · BTS-DAR-001");
$aid1 = $sc->saveAsset([
    'contract_id'   => $cid, 'site_id' => $sid, 'asset_type_id' => $genId,
    'asset_no'      => 'GEN-001-PRIM', 'serial_no' => 'PERK-2024-8891',
    'make'          => 'Perkins', 'model' => '4008-30TAG3A',
    'size_value'    => 80, 'size_unit' => 'kVA',
    'install_date'  => date('Y-m-d', strtotime('-1 year')),
    'is_active'     => 1,
]);
$aid2 = $sc->saveAsset([
    'contract_id'   => $cid, 'site_id' => $sid, 'asset_type_id' => $genId,
    'asset_no'      => 'GEN-002-BACKUP', 'serial_no' => 'CUMM-2024-2213',
    'make'          => 'Cummins', 'model' => 'C110D5',
    'size_value'    => 100, 'size_unit' => 'kVA',
    'install_date'  => date('Y-m-d', strtotime('-6 months')),
    'is_active'     => 1,
]);
p("Assets: $aid1 (80kVA primary) + $aid2 (100kVA backup)");

/* ── 8. Seed a PM template + activate contract + generate schedule ─ */
h('8. Seed PM template, activate contract, generate PM schedule');
$tpl = new PmTemplates();
$tid = $tpl->saveHeader([
    'code'            => 'GEN_QUARTERLY_E2E',
    'name'            => 'Generator quarterly PM',
    'asset_type_id'   => $genId,
    'scope'           => 'ASSET',
    'cadence_type'    => 'MONTHS',
    'cadence_value'   => 3,
    'expected_minutes'=> 120,
    'is_active'       => 1,
    'description'     => 'Standard quarterly PM for all diesel gensets.',
], 0);
$tpl->saveItem(['template_id'=>$tid,'sort_order'=>1,'section'=>'Engine','task'=>'Oil level check','input_type'=>'CHECK','is_required'=>1]);
$tpl->saveItem(['template_id'=>$tid,'sort_order'=>2,'section'=>'Engine','task'=>'Coolant level','input_type'=>'CHECK','is_required'=>1]);
$tpl->saveItem(['template_id'=>$tid,'sort_order'=>3,'section'=>'Engine','task'=>'Run hours','input_type'=>'NUMBER','unit'=>'hrs','is_required'=>1]);
$tpl->saveItem(['template_id'=>$tid,'sort_order'=>4,'section'=>'Safety','task'=>'PPE photo','input_type'=>'PHOTO','is_required'=>1]);
$tpl->saveItem(['template_id'=>$tid,'sort_order'=>5,'section'=>'Sign-off','task'=>'Client signature','input_type'=>'SIGNATURE','is_required'=>1]);
p("PM template id=$tid · GEN_QUARTERLY_E2E · 5 items · 3-month cadence");

$sc->activate($cid, 0);
p("Contract flipped DRAFT → ACTIVE");
$rgen = $sc->generateSchedule($cid);
ok(!empty($rgen['ok']), "generateSchedule returned ok · added=" . ($rgen['added'] ?? 0));

/* ── 9. Summary ────────────────────────────────────────────────────── */
h('9. Summary');
$proj    = $pdo->query("SELECT project_no, project_name, project_type, crm_status FROM c_projects WHERE c0d=$projId")->fetch(PDO::FETCH_ASSOC);
$contract= $pdo->query("SELECT contract_no, status, contract_value, monthly_retainer, spare_policy, invoice_cadence FROM service_contracts WHERE c0d=$cid")->fetch(PDO::FETCH_ASSOC);
$schedule= $pdo->query("SELECT COUNT(*) FROM service_contract_pm_schedule WHERE contract_id=$cid")->fetchColumn();
$sites   = $pdo->query("SELECT COUNT(*) FROM service_contract_sites WHERE contract_id=$cid")->fetchColumn();
$assets  = $pdo->query("SELECT COUNT(*) FROM service_contract_assets WHERE contract_id=$cid")->fetchColumn();
p("Project    : {$proj['project_no']} · {$proj['project_name']}");
p("            type={$proj['project_type']} · crm_status={$proj['crm_status']}");
p("Contract   : {$contract['contract_no']} · status={$contract['status']}");
p("             value=" . number_format((float)$contract['contract_value']) . " TZS · monthly=" . number_format((float)$contract['monthly_retainer']));
p("             spare_policy={$contract['spare_policy']} · cadence={$contract['invoice_cadence']}");
p("Sites      : $sites");
p("Assets     : $assets");
p("PM schedule: $schedule row(s) auto-generated");
p("Ready for: FS to spawn PMs · Callouts intake · Monthly PDF report · Monthly invoice");

/* ── Cleanup ──────────────────────────────────────────────────────── */
h('Cleanup');
$pdo->exec("DELETE FROM service_contract_pm_schedule 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 pm_template_items WHERE template_id=$tid");
$pdo->exec("DELETE FROM pm_templates WHERE c0d=$tid");
p("All test data removed");
echo PHP_EOL;
