-- ============================================================
-- HMM demo carrier performance source data for PostgreSQL.
--
-- Target: AWS RDS for PostgreSQL, database postgres
-- Schema: hmm_demo
-- Redmine: #729
--
-- This script is idempotent. It owns only C001..C008 and their
-- 2025-02 through 2026-07 monthly demo rows. It never stores an
-- RDS endpoint, password, or certificate path.
--
-- Example:
--   PGPASSWORD="$PG_PASSWORD" psql \
--     "host=$PG_HOST port=5432 dbname=postgres user=$PG_USER \
--      sslmode=verify-full sslrootcert=$PG_SSL_ROOT_CERT" \
--     -X -f database/source/postgres_hmm_carrier_performance.sql
-- ============================================================

\set ON_ERROR_STOP on
\echo === HMM carrier performance demo: begin ===

BEGIN;

CREATE SCHEMA IF NOT EXISTS hmm_demo AUTHORIZATION postgres;
COMMENT ON SCHEMA hmm_demo IS
  'HMM federation demonstration data. All carrier names and KPI values are fictional.';

REVOKE CREATE ON SCHEMA hmm_demo FROM PUBLIC;

CREATE TABLE IF NOT EXISTS hmm_demo.carriers (
  carrier_code       VARCHAR(10)  PRIMARY KEY,
  carrier_name       VARCHAR(120) NOT NULL UNIQUE,
  country_code       CHAR(2)      NOT NULL CHECK (country_code ~ '^[A-Z]{2}$'),
  alliance_name      VARCHAR(80),
  service_region     VARCHAR(40)  NOT NULL,
  performance_tier  VARCHAR(10)  NOT NULL
      CHECK (performance_tier IN ('CORE', 'GROWTH', 'WATCH')),
  active             BOOLEAN      NOT NULL DEFAULT TRUE,
  created_at         TIMESTAMPTZ  NOT NULL DEFAULT CURRENT_TIMESTAMP
);

COMMENT ON TABLE hmm_demo.carriers IS
  'Fictional carrier master data for the HMM ADB and PostgreSQL federation demo.';
COMMENT ON COLUMN hmm_demo.carriers.carrier_code IS 'Fictional carrier identifier.';
COMMENT ON COLUMN hmm_demo.carriers.performance_tier IS
  'Demo portfolio tier: CORE, GROWTH, or WATCH.';

CREATE TABLE IF NOT EXISTS hmm_demo.carrier_monthly_performance (
  carrier_code              VARCHAR(10)   NOT NULL
      REFERENCES hmm_demo.carriers (carrier_code),
  performance_month         DATE          NOT NULL
      CHECK (performance_month = date_trunc('month', performance_month)::DATE),
  contracted_teu            INTEGER       NOT NULL CHECK (contracted_teu >= 0),
  shipped_teu               INTEGER       NOT NULL CHECK (shipped_teu >= 0),
  revenue_usd               NUMERIC(16,2) NOT NULL CHECK (revenue_usd >= 0),
  gross_margin_usd          NUMERIC(16,2) NOT NULL,
  schedule_reliability_pct  NUMERIC(5,2)  NOT NULL
      CHECK (schedule_reliability_pct BETWEEN 0 AND 100),
  vessel_utilization_pct    NUMERIC(5,2)  NOT NULL
      CHECK (vessel_utilization_pct BETWEEN 0 AND 100),
  claim_rate_pct            NUMERIC(5,2)  NOT NULL
      CHECK (claim_rate_pct BETWEEN 0 AND 100),
  yoy_growth_pct            NUMERIC(7,2)  NOT NULL,
  risk_level                VARCHAR(10)   NOT NULL
      CHECK (risk_level IN ('GREEN', 'AMBER', 'RED')),
  updated_at                TIMESTAMPTZ   NOT NULL,
  PRIMARY KEY (carrier_code, performance_month)
);

COMMENT ON TABLE hmm_demo.carrier_monthly_performance IS
  'Deterministic fictional monthly carrier KPIs for 2025-02 through 2026-07.';
COMMENT ON COLUMN hmm_demo.carrier_monthly_performance.performance_month IS
  'First calendar day of the KPI month.';
COMMENT ON COLUMN hmm_demo.carrier_monthly_performance.risk_level IS
  'Derived demo risk level based on margin, reliability, and claim rate.';

CREATE INDEX IF NOT EXISTS ix_carrier_perf_month
  ON hmm_demo.carrier_monthly_performance (performance_month, carrier_code);
CREATE INDEX IF NOT EXISTS ix_carrier_perf_risk
  ON hmm_demo.carrier_monthly_performance (risk_level, performance_month);

INSERT INTO hmm_demo.carriers (
  carrier_code,
  carrier_name,
  country_code,
  alliance_name,
  service_region,
  performance_tier,
  active
) VALUES
  ('C001', 'Bluewave Maritime',       'SG', 'North Pacific Network', 'ASIA-PACIFIC', 'CORE',   TRUE),
  ('C002', 'Pacific Star Lines',      'JP', 'East Ocean Connect',    'ASIA-PACIFIC', 'CORE',   TRUE),
  ('C003', 'Korea Ocean Link',        'KR', 'East Ocean Connect',    'ASIA-PACIFIC', 'GROWTH', TRUE),
  ('C004', 'Nordic Seaways',          'DK', 'Northern Trade Group',  'EUROPE',       'CORE',   TRUE),
  ('C005', 'Orient Bridge Shipping',  'TW', 'North Pacific Network', 'ASIA-PACIFIC', 'WATCH',  TRUE),
  ('C006', 'Atlantic Merchant Line',  'DE', 'Atlantic Cargo Forum',  'EUROPE-AMERICAS', 'WATCH', TRUE),
  ('C007', 'Global Horizon Cargo',    'US', 'Atlantic Cargo Forum',  'AMERICAS',     'GROWTH', TRUE),
  ('C008', 'Southern Cross Marine',   'FR', 'Southern Ocean Group',  'OCEANIA',      'WATCH',  TRUE)
ON CONFLICT (carrier_code) DO UPDATE SET
  carrier_name      = EXCLUDED.carrier_name,
  country_code      = EXCLUDED.country_code,
  alliance_name     = EXCLUDED.alliance_name,
  service_region    = EXCLUDED.service_region,
  performance_tier = EXCLUDED.performance_tier,
  active            = EXCLUDED.active;

WITH month_series AS (
  SELECT
    month_index,
    (DATE '2025-02-01' + make_interval(months => month_index))::DATE AS performance_month,
    CASE month_index % 6
      WHEN 0 THEN -1
      WHEN 1 THEN 0
      WHEN 2 THEN 1
      WHEN 3 THEN 2
      WHEN 4 THEN 1
      ELSE -1
    END::NUMERIC AS seasonal_factor
  FROM generate_series(0, 17) AS series(month_index)
),
profiles (
  carrier_code,
  base_teu,
  monthly_teu_step,
  seasonal_teu,
  utilization_base,
  utilization_step,
  revenue_per_teu,
  revenue_step,
  margin_pct_base,
  margin_pct_step,
  reliability_base,
  reliability_step,
  claim_rate_base,
  claim_rate_step,
  yoy_growth_base,
  yoy_growth_step
) AS (
  VALUES
    ('C001', 1800::NUMERIC,  25::NUMERIC,  80::NUMERIC, 91.5::NUMERIC,  0.10::NUMERIC, 1850::NUMERIC,  4::NUMERIC, 15.0::NUMERIC,  0.10::NUMERIC, 95.0::NUMERIC,  0.05::NUMERIC, 0.35::NUMERIC, -0.005::NUMERIC,  8.0::NUMERIC,  0.25::NUMERIC),
    ('C002', 1500::NUMERIC,   5::NUMERIC,  60::NUMERIC, 88.5::NUMERIC,  0.02::NUMERIC, 1780::NUMERIC,  3::NUMERIC, 12.0::NUMERIC,  0.00::NUMERIC, 92.5::NUMERIC,  0.00::NUMERIC, 0.45::NUMERIC,  0.005::NUMERIC,  3.0::NUMERIC,  0.05::NUMERIC),
    ('C003', 1050::NUMERIC,  15::NUMERIC,  50::NUMERIC, 83.0::NUMERIC,  0.20::NUMERIC, 1920::NUMERIC,  2::NUMERIC,  8.0::NUMERIC,  0.15::NUMERIC, 88.5::NUMERIC,  0.25::NUMERIC, 1.20::NUMERIC, -0.040::NUMERIC, -4.0::NUMERIC,  0.60::NUMERIC),
    ('C004', 1350::NUMERIC,   0::NUMERIC, 180::NUMERIC, 86.0::NUMERIC,  0.00::NUMERIC, 1810::NUMERIC,  3::NUMERIC, 10.0::NUMERIC,  0.00::NUMERIC, 93.0::NUMERIC,  0.00::NUMERIC, 0.55::NUMERIC,  0.010::NUMERIC,  1.0::NUMERIC,  0.10::NUMERIC),
    ('C005', 1300::NUMERIC, -20::NUMERIC,  70::NUMERIC, 88.0::NUMERIC, -0.10::NUMERIC, 1850::NUMERIC, -2::NUMERIC,  8.0::NUMERIC, -0.20::NUMERIC, 91.0::NUMERIC, -0.15::NUMERIC, 0.80::NUMERIC,  0.030::NUMERIC, -2.0::NUMERIC, -0.50::NUMERIC),
    ('C006', 1250::NUMERIC, -10::NUMERIC,  90::NUMERIC, 84.0::NUMERIC, -0.12::NUMERIC, 1800::NUMERIC, -3::NUMERIC,  6.0::NUMERIC, -0.15::NUMERIC, 87.0::NUMERIC, -0.25::NUMERIC, 1.50::NUMERIC,  0.050::NUMERIC, -5.0::NUMERIC, -0.70::NUMERIC),
    ('C007',  800::NUMERIC,  30::NUMERIC, 100::NUMERIC, 82.0::NUMERIC,  0.25::NUMERIC, 2050::NUMERIC,  5::NUMERIC,  9.0::NUMERIC,  0.18::NUMERIC, 90.5::NUMERIC,  0.15::NUMERIC, 0.70::NUMERIC, -0.020::NUMERIC, 12.0::NUMERIC,  0.50::NUMERIC),
    ('C008', 1150::NUMERIC, -25::NUMERIC,  60::NUMERIC, 80.0::NUMERIC, -0.15::NUMERIC, 1750::NUMERIC, -4::NUMERIC,  3.0::NUMERIC, -0.20::NUMERIC, 85.0::NUMERIC, -0.30::NUMERIC, 2.00::NUMERIC,  0.080::NUMERIC, -8.0::NUMERIC, -0.80::NUMERIC)
),
base_metrics AS (
  SELECT
    p.carrier_code,
    m.performance_month,
    ROUND(
      p.base_teu
      + p.monthly_teu_step * m.month_index
      + p.seasonal_teu * m.seasonal_factor
    )::INTEGER AS contracted_teu,
    LEAST(
      98.0::NUMERIC,
      GREATEST(
        60.0::NUMERIC,
        p.utilization_base
        + p.utilization_step * m.month_index
        + m.seasonal_factor * 0.50
      )
    ) AS utilization_pct,
    p.revenue_per_teu + p.revenue_step * m.month_index AS unit_revenue,
    p.margin_pct_base + p.margin_pct_step * m.month_index AS margin_pct,
    LEAST(
      99.5::NUMERIC,
      GREATEST(
        60.0::NUMERIC,
        p.reliability_base
        + p.reliability_step * m.month_index
        + m.seasonal_factor * 0.20
      )
    ) AS reliability_pct,
    LEAST(
      100.0::NUMERIC,
      GREATEST(
        0.0::NUMERIC,
        p.claim_rate_base + p.claim_rate_step * m.month_index
      )
    ) AS claim_pct,
    p.yoy_growth_base + p.yoy_growth_step * m.month_index AS yoy_pct
  FROM profiles p
  CROSS JOIN month_series m
),
volume_metrics AS (
  SELECT
    b.*,
    ROUND(b.contracted_teu * b.utilization_pct / 100.0)::INTEGER AS shipped_teu
  FROM base_metrics b
),
financial_metrics AS (
  SELECT
    v.*,
    ROUND(v.shipped_teu * v.unit_revenue, 2) AS revenue_usd
  FROM volume_metrics v
),
final_metrics AS (
  SELECT
    f.*,
    ROUND(f.revenue_usd * f.margin_pct / 100.0, 2) AS gross_margin_usd
  FROM financial_metrics f
)
INSERT INTO hmm_demo.carrier_monthly_performance (
  carrier_code,
  performance_month,
  contracted_teu,
  shipped_teu,
  revenue_usd,
  gross_margin_usd,
  schedule_reliability_pct,
  vessel_utilization_pct,
  claim_rate_pct,
  yoy_growth_pct,
  risk_level,
  updated_at
)
SELECT
  f.carrier_code,
  f.performance_month,
  f.contracted_teu,
  f.shipped_teu,
  f.revenue_usd,
  f.gross_margin_usd,
  ROUND(f.reliability_pct, 2),
  ROUND(f.utilization_pct, 2),
  ROUND(f.claim_pct, 2),
  ROUND(f.yoy_pct, 2),
  CASE
    WHEN f.gross_margin_usd < 0
      OR f.reliability_pct < 87
      OR f.claim_pct >= 2 THEN 'RED'
    WHEN f.margin_pct < 7
      OR f.reliability_pct < 92
      OR f.claim_pct >= 1 THEN 'AMBER'
    ELSE 'GREEN'
  END,
  TIMESTAMPTZ '2026-07-24 00:00:00+00'
FROM final_metrics f
ON CONFLICT (carrier_code, performance_month) DO UPDATE SET
  contracted_teu           = EXCLUDED.contracted_teu,
  shipped_teu              = EXCLUDED.shipped_teu,
  revenue_usd              = EXCLUDED.revenue_usd,
  gross_margin_usd         = EXCLUDED.gross_margin_usd,
  schedule_reliability_pct = EXCLUDED.schedule_reliability_pct,
  vessel_utilization_pct   = EXCLUDED.vessel_utilization_pct,
  claim_rate_pct           = EXCLUDED.claim_rate_pct,
  yoy_growth_pct           = EXCLUDED.yoy_growth_pct,
  risk_level               = EXCLUDED.risk_level,
  updated_at               = EXCLUDED.updated_at;

CREATE OR REPLACE VIEW hmm_demo.carrier_performance_latest_v AS
SELECT
  c.carrier_code,
  c.carrier_name,
  c.country_code,
  c.alliance_name,
  c.service_region,
  c.performance_tier,
  p.performance_month,
  p.contracted_teu,
  p.shipped_teu,
  p.revenue_usd,
  p.gross_margin_usd,
  p.schedule_reliability_pct,
  p.vessel_utilization_pct,
  p.claim_rate_pct,
  p.yoy_growth_pct,
  p.risk_level
FROM hmm_demo.carriers c
JOIN hmm_demo.carrier_monthly_performance p
  ON p.carrier_code = c.carrier_code
WHERE p.performance_month = (
  SELECT MAX(latest.performance_month)
  FROM hmm_demo.carrier_monthly_performance latest
);

COMMENT ON VIEW hmm_demo.carrier_performance_latest_v IS
  'Latest fictional monthly KPI for each active demo carrier.';

DO $role$
BEGIN
  IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'hmm_federation_reader') THEN
    CREATE ROLE hmm_federation_reader NOLOGIN;
  END IF;
END
$role$;

GRANT USAGE ON SCHEMA hmm_demo TO hmm_federation_reader;
GRANT SELECT ON ALL TABLES IN SCHEMA hmm_demo TO hmm_federation_reader;
ALTER DEFAULT PRIVILEGES IN SCHEMA hmm_demo
  GRANT SELECT ON TABLES TO hmm_federation_reader;

COMMIT;

\echo === HMM carrier performance demo: complete ===
\echo Next: run database/source/postgres_hmm_carrier_performance_verify.sql
