-- ============================================================================
-- Migration 026 - Risk quantitativo FAIR + KRI (P2)
-- ----------------------------------------------------------------------------
-- Affianca al risk register qualitativo (likelihood/impact 1-5) l'analisi
-- quantitativa FAIR (Factor Analysis of Information Risk) in valore economico:
--   - parametri FAIR su risks (TEF, vulnerability, loss magnitude PERT min/ml/max)
--   - ale_min / ale_ml / ale_max / ale_mean: Annualized Loss Expectancy (EUR)
--     calcolati via Monte Carlo e persistiti.
--   - tabella kri: Key Risk Indicators con soglie e valori correnti.
--
-- Idempotente. Rilanciabile.
--   mysql -h localhost nis2_agile_db -e "source docs/sql/026_risk_quantitative.sql"
-- ============================================================================

DELIMITER //
DROP PROCEDURE IF EXISTS _mig026_col //
CREATE PROCEDURE _mig026_col(IN col VARCHAR(64), IN ddl TEXT)
BEGIN
    IF NOT EXISTS (SELECT 1 FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='risks' AND COLUMN_NAME=col) THEN
        SET @sql = CONCAT('ALTER TABLE risks ADD COLUMN ', ddl);
        PREPARE st FROM @sql; EXECUTE st; DEALLOCATE PREPARE st;
    END IF;
END //
DELIMITER ;

-- Parametri FAIR (input)
CALL _mig026_col('fair_tef_min',   "fair_tef_min DECIMAL(10,2) NULL COMMENT 'Threat Event Frequency min (eventi/anno)'");
CALL _mig026_col('fair_tef_ml',    "fair_tef_ml DECIMAL(10,2) NULL COMMENT 'Threat Event Frequency most likely (eventi/anno)'");
CALL _mig026_col('fair_tef_max',   "fair_tef_max DECIMAL(10,2) NULL COMMENT 'Threat Event Frequency max (eventi/anno)'");
CALL _mig026_col('fair_vuln',      "fair_vuln DECIMAL(5,4) NULL COMMENT 'Vulnerability: prob. che una minaccia diventi perdita (0-1)'");
CALL _mig026_col('fair_lm_min',    "fair_lm_min DECIMAL(14,2) NULL COMMENT 'Loss Magnitude min (EUR per evento)'");
CALL _mig026_col('fair_lm_ml',     "fair_lm_ml DECIMAL(14,2) NULL COMMENT 'Loss Magnitude most likely (EUR per evento)'");
CALL _mig026_col('fair_lm_max',    "fair_lm_max DECIMAL(14,2) NULL COMMENT 'Loss Magnitude max (EUR per evento)'");
-- Risultati FAIR (output ALE in EUR)
CALL _mig026_col('ale_min',        "ale_min DECIMAL(16,2) NULL COMMENT 'Annualized Loss Expectancy - percentile basso (P10)'");
CALL _mig026_col('ale_ml',         "ale_ml DECIMAL(16,2) NULL COMMENT 'Annualized Loss Expectancy - mediana (P50)'");
CALL _mig026_col('ale_max',        "ale_max DECIMAL(16,2) NULL COMMENT 'Annualized Loss Expectancy - percentile alto (P90)'");
CALL _mig026_col('ale_mean',       "ale_mean DECIMAL(16,2) NULL COMMENT 'Annualized Loss Expectancy - media simulazione'");
CALL _mig026_col('fair_computed_at',"fair_computed_at DATETIME NULL COMMENT 'Ultimo calcolo FAIR'");

DROP PROCEDURE IF EXISTS _mig026_col;

-- Key Risk Indicators
CREATE TABLE IF NOT EXISTS kri (
    id              INT NOT NULL AUTO_INCREMENT,
    organization_id INT NOT NULL,
    name            VARCHAR(160) NOT NULL,
    description     VARCHAR(255) NULL,
    category        ENUM('cyber','operational','compliance','supply_chain','physical','human') NOT NULL DEFAULT 'cyber',
    unit            VARCHAR(40) NULL COMMENT 'Unita di misura (%, count, EUR, giorni)',
    current_value   DECIMAL(16,4) NULL,
    target_value    DECIMAL(16,4) NULL COMMENT 'Valore obiettivo/atteso',
    threshold_warning DECIMAL(16,4) NULL COMMENT 'Soglia ambra',
    threshold_critical DECIMAL(16,4) NULL COMMENT 'Soglia rossa',
    direction       ENUM('higher_worse','lower_worse') NOT NULL DEFAULT 'higher_worse' COMMENT 'Se valori alti=peggio o bassi=peggio',
    status          ENUM('green','amber','red','unknown') NOT NULL DEFAULT 'unknown',
    linked_risk_id  INT NULL,
    measured_at     DATETIME NULL,
    created_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    updated_at      DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    PRIMARY KEY (id),
    KEY idx_kri_org (organization_id),
    KEY idx_kri_risk (linked_risk_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
  COMMENT='Key Risk Indicators con soglie e stato semaforo';

-- ROLLBACK:
-- DROP TABLE IF EXISTS kri;
-- ALTER TABLE risks DROP COLUMN fair_tef_min, DROP COLUMN fair_tef_ml, DROP COLUMN fair_tef_max,
--   DROP COLUMN fair_vuln, DROP COLUMN fair_lm_min, DROP COLUMN fair_lm_ml, DROP COLUMN fair_lm_max,
--   DROP COLUMN ale_min, DROP COLUMN ale_ml, DROP COLUMN ale_max, DROP COLUMN ale_mean, DROP COLUMN fair_computed_at;
