-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Migration 08 — Analytics Configuration Tables
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
-- Adds reference data driving the three-stakeholder analytics redesign
-- (Phase 0.3 of the plan). These tables let downstream views monetise idle
-- and fuel costs, and apply traffic-light targets to KPIs without hard-coding
-- thresholds in SQL.
--
--   • ops.cost_rates    — fuel price per litre by city, labour rate by role.
--   • ops.kpi_targets   — green / amber / red thresholds per KPI per scope.
--
-- Run after migration 07. Safe to re-run (CREATE TABLE IF NOT EXISTS,
-- INSERT ... ON CONFLICT DO NOTHING).
-- ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

BEGIN;

-- ── 1. ops.cost_rates ───────────────────────────────────────────────────────
-- Reference rates that power monetisation in analytics views. Lookup pattern
-- in views: WHERE scope_type = 'city' AND scope_value = <city> AND metric = ...
-- ORDER BY effective_from DESC LIMIT 1.

CREATE TABLE IF NOT EXISTS ops.cost_rates (
  rate_key        TEXT          PRIMARY KEY,
  scope_type      TEXT          NOT NULL,            -- 'city' | 'role' | 'global'
  scope_value     TEXT,                              -- 'nairobi' | 'driver' | NULL for global
  metric          TEXT          NOT NULL,            -- 'fuel_per_litre' | 'labour_per_hour'
  amount          NUMERIC(12,2) NOT NULL,
  currency        TEXT          NOT NULL,            -- 'KES' | 'UGX'
  effective_from  DATE          NOT NULL DEFAULT CURRENT_DATE,
  notes           TEXT,
  created_at      TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  updated_at      TIMESTAMPTZ   NOT NULL DEFAULT NOW()
);

CREATE INDEX IF NOT EXISTS idx_cost_rates_lookup
  ON ops.cost_rates (scope_type, scope_value, metric, effective_from DESC);

COMMENT ON TABLE ops.cost_rates
  IS 'Reference rates for analytics monetisation: fuel price per litre by city, '
     'labour cost per hour by role. Resolution order in views: scope_type=city '
     '> scope_type=role > scope_type=global.';
COMMENT ON COLUMN ops.cost_rates.metric
  IS 'fuel_per_litre | labour_per_hour';
COMMENT ON COLUMN ops.cost_rates.scope_type
  IS 'city | role | global';

-- ── 2. ops.kpi_targets ──────────────────────────────────────────────────────
-- Traffic-light thresholds per KPI. Same KPI can have global + per-CC + per-city
-- rows; views use a CASE / COALESCE chain to pick the most specific match.

CREATE TABLE IF NOT EXISTS ops.kpi_targets (
  target_id        BIGSERIAL     PRIMARY KEY,
  kpi_key          TEXT          NOT NULL,           -- e.g. 'utilisation_pct'
  scope_type       TEXT          NOT NULL,           -- 'global' | 'city' | 'cost_centre' | 'vehicle_category'
  scope_value      TEXT,                             -- NULL for global
  target_value     NUMERIC(12,2) NOT NULL,
  amber_threshold  NUMERIC(12,2),                    -- between target and red
  red_threshold    NUMERIC(12,2),                    -- worse than amber
  direction        TEXT          NOT NULL DEFAULT 'higher_is_better',
                                                     -- 'higher_is_better' | 'lower_is_better'
  effective_from   DATE          NOT NULL DEFAULT CURRENT_DATE,
  notes            TEXT,
  created_at       TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  updated_at       TIMESTAMPTZ   NOT NULL DEFAULT NOW(),
  UNIQUE (kpi_key, scope_type, scope_value, effective_from)
);

CREATE INDEX IF NOT EXISTS idx_kpi_targets_lookup
  ON ops.kpi_targets (kpi_key, scope_type, scope_value, effective_from DESC);

COMMENT ON TABLE ops.kpi_targets
  IS 'Traffic-light targets per KPI per scope. Resolution order in views: '
     'cost_centre > vehicle_category > city > global.';
COMMENT ON COLUMN ops.kpi_targets.direction
  IS 'higher_is_better -> green when value >= target. '
     'lower_is_better  -> green when value <= target.';

-- ── 3. Seed cost rates ──────────────────────────────────────────────────────
-- Placeholder values — confirm with Finance and update via a follow-up insert
-- with a later effective_from date (do NOT mutate historical rows).

INSERT INTO ops.cost_rates
  (rate_key, scope_type, scope_value, metric, amount, currency, notes)
VALUES
  ('fuel.nairobi', 'city', 'nairobi', 'fuel_per_litre',  195.00, 'KES',
   'Placeholder pump price — confirm with Finance.'),
  ('fuel.mombasa', 'city', 'mombasa', 'fuel_per_litre',  195.00, 'KES',
   'Placeholder pump price — confirm with Finance.'),
  ('fuel.kampala', 'city', 'kampala', 'fuel_per_litre', 5200.00, 'UGX',
   'Placeholder pump price — confirm with Finance.')
ON CONFLICT (rate_key) DO NOTHING;

-- ── 4. Seed KPI targets ─────────────────────────────────────────────────────
-- Initial Exco-relevant targets. Calibrate after one month of clean data.

INSERT INTO ops.kpi_targets
  (kpi_key, scope_type, scope_value, target_value, amber_threshold,
   red_threshold, direction, notes)
VALUES
  ('utilisation_pct',     'global',      NULL,        70, 60, 50, 'higher_is_better',
   'Fleet utilisation: drive_hours / engine_on_hours.'),
  ('idle_pct',            'global',      NULL,        15, 20, 25, 'lower_is_better',
   'Idle as % of engine-on time.'),
  ('idle_pct',            'cost_centre', 'osp patrol', 15, 20, 25, 'lower_is_better',
   'OSP patrol idle target — same as global until calibrated.'),
  ('fuel_kes_per_100km',  'global',      NULL,        12, 14, 16, 'lower_is_better',
   'Fuel litres per 100km equivalent — uses fuel_100km on devices.'),
  ('mttr_hours',          'global',      NULL,         4,  6,  8, 'lower_is_better',
   'Mean Time To Resolve, field-service ticket.'),
  ('alarms_per_100km',    'global',      NULL,         2,  3,  5, 'lower_is_better',
   'Safety event density.')
ON CONFLICT (kpi_key, scope_type, scope_value, effective_from) DO NOTHING;

-- ── 5. Read access for Grafana ──────────────────────────────────────────────

GRANT USAGE  ON SCHEMA ops             TO grafana_ro;
GRANT SELECT ON ops.cost_rates         TO grafana_ro;
GRANT SELECT ON ops.kpi_targets        TO grafana_ro;

COMMIT;
