"""
╔══════════════════════════════════════════════════════════════════╗
║     GCC GOVERNMENT & HR AI — 10 Model Mega Batch                ║
║     AgenThink | Kuwait City                                      ║
║                                                                  ║
║  Models:                                                         ║
║   1.  Kuwait Civil Service Attrition (classification)            ║
║   2.  Expat Visa Approval Prediction (classification)            ║
║   3.  Government Project Delay Risk (classification)             ║
║   4.  Public Sector Budget Forecasting (regression)              ║
║   5.  Kuwaitization / Nationalization Rate (regression)          ║
║   6.  Employee Performance Prediction (regression)               ║
║   7.  Public Services Demand Forecasting (regression)            ║
║   8.  Government Procurement Fraud Detection (classification)    ║
║   9.  Salary Benchmarking & Pay Gap (regression)                 ║
║  10.  Workforce Succession Planning (classification)             ║
╚══════════════════════════════════════════════════════════════════╝
"""

import numpy as np
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import warnings, json, os, joblib
from sklearn.ensemble import (RandomForestRegressor, RandomForestClassifier,
                               GradientBoostingRegressor, GradientBoostingClassifier,
                               ExtraTreesRegressor, ExtraTreesClassifier)
from sklearn.linear_model import Ridge, LogisticRegression
from sklearn.tree import DecisionTreeRegressor, DecisionTreeClassifier
from sklearn.model_selection import cross_val_score, train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_absolute_error, r2_score, accuracy_score

warnings.filterwarnings('ignore')
np.random.seed(42)

OUT = "/home/claude/gcc_government_hr_ai"
os.makedirs(OUT, exist_ok=True)

DARK=  "#0A0E1A"; GOLD="#C9A84C"; TEAL="#2DD4BF"
GREEN= "#34D399"; RED="#F87171"; BLUE="#60A5FA"
PURPLE="#A78BFA"; WHITE="#F9FAFB"; ORANGE="#FB923C"
CYAN=  "#67E8F9"

print("="*65)
print("  GCC GOVERNMENT & HR AI — 10 Model Mega Batch")
print("  AgenThink | Kuwait City")
print("="*65)

def automl_reg(X_tr, y_tr, name):
    cands = {
        "RandomForest":     RandomForestRegressor(n_estimators=80, max_depth=10, random_state=42, n_jobs=-1),
        "GradientBoosting": GradientBoostingRegressor(n_estimators=80, max_depth=4, learning_rate=0.1, random_state=42),
        "ExtraTrees":       ExtraTreesRegressor(n_estimators=80, max_depth=10, random_state=42, n_jobs=-1),
        "Ridge":            Ridge(alpha=10.0),
        "DecisionTree":     DecisionTreeRegressor(max_depth=8, random_state=42),
    }
    best_name, best_model, best_sc = "RandomForest", None, -np.inf
    all_sc = {}
    for n, m in cands.items():
        try:
            sc = float(cross_val_score(m, X_tr, y_tr, cv=3, scoring="r2", n_jobs=-1).mean())
            all_sc[n] = round(sc, 4)
            if sc > best_sc: best_sc, best_name, best_model = sc, n, m
        except: pass
    if best_model is None:
        best_model = RandomForestRegressor(n_estimators=80, random_state=42, n_jobs=-1)
    best_model.fit(X_tr, y_tr)
    print(f"  [{name}] best={best_name} CV-R²={best_sc:.3f}")
    return best_model, best_name, float(best_sc), all_sc

def automl_clf(X_tr, y_tr, name):
    cands = {
        "RandomForest":       RandomForestClassifier(n_estimators=80, max_depth=10, random_state=42, n_jobs=-1),
        "GradientBoosting":   GradientBoostingClassifier(n_estimators=80, max_depth=4, learning_rate=0.1, random_state=42),
        "ExtraTrees":         ExtraTreesClassifier(n_estimators=80, max_depth=10, random_state=42, n_jobs=-1),
        "LogisticRegression": LogisticRegression(max_iter=300, random_state=42),
        "DecisionTree":       DecisionTreeClassifier(max_depth=8, random_state=42),
    }
    best_name, best_model, best_sc = "RandomForest", None, -np.inf
    all_sc = {}
    for n, m in cands.items():
        try:
            sc = float(cross_val_score(m, X_tr, y_tr, cv=3, scoring="accuracy", n_jobs=-1).mean())
            all_sc[n] = round(sc, 4)
            if sc > best_sc: best_sc, best_name, best_model = sc, n, m
        except: pass
    if best_model is None:
        best_model = RandomForestClassifier(n_estimators=80, random_state=42, n_jobs=-1)
    best_model.fit(X_tr, y_tr)
    print(f"  [{name}] best={best_name} CV-Acc={best_sc:.3f}")
    return best_model, best_name, float(best_sc), all_sc

def feat_imp(model, features):
    try:    imp = model.feature_importances_
    except:
        try:    imp = np.abs(model.coef_).flatten(); imp = imp / (imp.sum() + 1e-9)
        except: return {}
    return dict(zip(features, np.round(imp.tolist(), 4)))

results = {}
models  = {}
N = 12000

# ════════════════════════════════════════════════════════════════
# MODEL 1 — KUWAIT CIVIL SERVICE ATTRITION
# ════════════════════════════════════════════════════════════════
print("\n[1/10] Kuwait Civil Service Attrition")
ministries = ["MOH","MOE","MOI","MOFA","MOJ","MOF","MOCI","PACI","CSB","KPC","KIA","Other"]
le1m = LabelEncoder().fit(ministries)
grades = ["Grade1","Grade2","Grade3","Grade4","Grade5","Grade6","Grade7","Grade8","Grade9","Grade10"]
le1g = LabelEncoder().fit(grades)

df1 = pd.DataFrame({
    "ministry":             np.random.choice(ministries, N),
    "grade":                np.random.choice(grades, N),
    "age":                  np.random.randint(22, 62, N),
    "years_of_service":     np.random.exponential(10, N).clip(0, 35),
    "is_kuwaiti":           np.random.binomial(1, 0.75, N),
    "is_female":            np.random.binomial(1, 0.52, N),  # high female govt workforce in Kuwait
    "salary_kwd":           np.random.normal(1200, 500, N).clip(300, 5000),
    "allowances_kwd":       np.random.normal(400, 200, N).clip(0, 2000),
    "performance_rating":   np.random.choice([1,2,3,4,5], N, p=[0.05,0.10,0.30,0.35,0.20]),
    "promotions_last5yr":   np.random.poisson(0.8, N).clip(0, 4),
    "training_days_yr":     np.random.poisson(8, N).clip(0, 60),
    "absenteeism_days_yr":  np.random.poisson(6, N).clip(0, 90),
    "overtime_hours_mo":    np.random.exponential(5, N).clip(0, 80),
    "commute_km":           np.random.exponential(15, N).clip(1, 80),
    "has_second_job":       np.random.binomial(1, 0.15, N),
    "manager_satisfaction": np.random.choice([1,2,3,4,5], N),
    "peer_satisfaction":    np.random.choice([1,2,3,4,5], N),
    "years_to_retirement":  np.random.randint(0, 35, N),
    "pension_eligibility":  np.random.binomial(1, 0.40, N),
    "remote_work_days":     np.random.poisson(1.5, N).clip(0, 5),
})
df1["ministry_enc"] = le1m.transform(df1["ministry"])
df1["grade_enc"]    = le1g.transform(df1["grade"])
attrition_risk = (
    (df1["years_to_retirement"] < 3).astype(int) * 3 +
    (df1["performance_rating"] < 2).astype(int) * 2 +
    (df1["absenteeism_days_yr"] > 20).astype(int) * 2 +
    df1["has_second_job"] * 1.5 +
    (df1["manager_satisfaction"] < 2).astype(int) * 1.5 +
    (df1["promotions_last5yr"] == 0).astype(int) * 1 +
    (df1["training_days_yr"] < 2).astype(int) * 0.5 +
    np.random.exponential(0.4, N)
)
df1["will_leave"] = (attrition_risk >= attrition_risk.quantile(0.80)).astype(int)
feats1 = ["ministry_enc","grade_enc","age","years_of_service","is_kuwaiti","is_female",
          "salary_kwd","allowances_kwd","performance_rating","promotions_last5yr",
          "training_days_yr","absenteeism_days_yr","overtime_hours_mo","commute_km",
          "has_second_job","manager_satisfaction","peer_satisfaction",
          "years_to_retirement","pension_eligibility","remote_work_days"]
X1, y1 = df1[feats1].fillna(0), df1["will_leave"]
X1tr,X1te,y1tr,y1te = train_test_split(X1,y1,test_size=0.2,random_state=42)
m1,m1n,m1cv,m1a = automl_clf(X1tr,y1tr,"Civil Service Attrition")
y1p = m1.predict(X1te)
results["civil_attrition"] = {"type":"classification","task":"Kuwait Civil Service Attrition",
    "best_algo":m1n,"cv_acc":m1cv,"test_acc":round(float(accuracy_score(y1te,y1p)),4),
    "all_scores":m1a,"features":feats1,"feature_importance":feat_imp(m1,feats1),
    "classes":["Stay","Leave"],"n_samples":N,
    "gcc_note":"75% of Kuwait govt workforce is Kuwaiti national — retirement cliff risk"}
models["civil_attrition"] = m1

# ════════════════════════════════════════════════════════════════
# MODEL 2 — EXPAT VISA APPROVAL PREDICTION
# ════════════════════════════════════════════════════════════════
print("\n[2/10] Expat Visa Approval Prediction")
visa_types   = ["Work","Family","Domestic","Investor","Student","Transit"]
nationalities = ["Indian","Egyptian","Filipino","Pakistani","Bangladeshi","Nepalese",
                 "Sri Lankan","Indonesian","Western","Arab-Other","Syrian","Jordanian"]
sectors      = ["Construction","Healthcare","Education","Retail","Hospitality",
                "Finance","Technology","Oil&Gas","Domestic","Other"]
le2v = LabelEncoder().fit(visa_types)
le2n = LabelEncoder().fit(nationalities)
le2s = LabelEncoder().fit(sectors)

df2 = pd.DataFrame({
    "visa_type":            np.random.choice(visa_types, N, p=[0.45,0.25,0.12,0.05,0.08,0.05]),
    "nationality":          np.random.choice(nationalities, N,
                                p=[0.25,0.12,0.10,0.10,0.08,0.06,0.05,0.05,0.06,0.05,0.04,0.04]),
    "sector":               np.random.choice(sectors, N, p=[0.20,0.10,0.08,0.10,0.08,0.07,0.07,0.08,0.12,0.10]),
    "age":                  np.random.randint(18, 60, N),
    "education_level":      np.random.choice([1,2,3,4,5], N, p=[0.10,0.20,0.35,0.25,0.10]),
    "salary_offered_kwd":   np.random.lognormal(6.5, 0.8, N).clip(100, 5000),
    "sponsor_category":     np.random.choice([1,2,3,4], N, p=[0.40,0.30,0.20,0.10]),
    "sponsor_compliance":   np.random.beta(6, 2, N),
    "years_in_gcc_prev":    np.random.exponential(3, N).clip(0, 20),
    "criminal_record":      np.random.binomial(1, 0.03, N),
    "medical_clearance":    np.random.binomial(1, 0.92, N),
    "docs_complete":        np.random.binomial(1, 0.85, N),
    "quota_available":      np.random.binomial(1, 0.70, N),
    "previous_violations":  np.random.poisson(0.1, N).clip(0, 5),
    "role_in_demand":       np.random.binomial(1, 0.55, N),
    "oil_price_env":        np.random.uniform(40, 120, N),
    "nationalization_pct":  np.random.beta(2, 5, N),
    "bilateral_agreement":  np.random.binomial(1, 0.60, N),
    "processing_days":      np.random.exponential(15, N).clip(1, 120),
    "application_month":    np.random.randint(1, 13, N),
})
df2["vtype_enc"] = le2v.transform(df2["visa_type"])
df2["nat_enc"]   = le2n.transform(df2["nationality"])
df2["sec_enc"]   = le2s.transform(df2["sector"])
approval = (
    (df2["criminal_record"] == 0).astype(int) * 2 +
    df2["medical_clearance"] * 2 +
    df2["docs_complete"] * 2 +
    df2["quota_available"] * 1.5 +
    df2["role_in_demand"] * 1 +
    df2["bilateral_agreement"] * 0.5 +
    df2["sponsor_compliance"] * 1.5 +
    (df2["previous_violations"] == 0).astype(int) * 1 +
    np.random.normal(0, 0.5, N)
)
df2["approved"] = (approval >= approval.quantile(0.35)).astype(int)
feats2 = ["vtype_enc","nat_enc","sec_enc","age","education_level","salary_offered_kwd",
          "sponsor_category","sponsor_compliance","years_in_gcc_prev","criminal_record",
          "medical_clearance","docs_complete","quota_available","previous_violations",
          "role_in_demand","oil_price_env","nationalization_pct","bilateral_agreement",
          "processing_days","application_month"]
X2, y2 = df2[feats2].fillna(0), df2["approved"]
X2tr,X2te,y2tr,y2te = train_test_split(X2,y2,test_size=0.2,random_state=42)
m2,m2n,m2cv,m2a = automl_clf(X2tr,y2tr,"Visa Approval")
y2p = m2.predict(X2te)
results["visa_approval"] = {"type":"classification","task":"Expat Visa Approval Prediction",
    "best_algo":m2n,"cv_acc":m2cv,"test_acc":round(float(accuracy_score(y2te,y2p)),4),
    "all_scores":m2a,"features":feats2,"feature_importance":feat_imp(m2,feats2),
    "classes":["Rejected","Approved"],"n_samples":N,
    "gcc_note":"GCC has world's highest expat ratio — visa policy directly impacts GDP"}
models["visa_approval"] = m2

# ════════════════════════════════════════════════════════════════
# MODEL 3 — GOVERNMENT PROJECT DELAY RISK
# ════════════════════════════════════════════════════════════════
print("\n[3/10] Government Project Delay Risk")
proj_types  = ["Infrastructure","IT","Healthcare","Education","Housing","Defense","Energy","Social"]
le3p = LabelEncoder().fit(proj_types)

df3 = pd.DataFrame({
    "project_type":         np.random.choice(proj_types, N, p=[0.25,0.15,0.12,0.10,0.12,0.08,0.10,0.08]),
    "budget_mkwd":          np.random.lognormal(4, 1.8, N).clip(0.1, 2000),
    "planned_months":       np.random.randint(3, 120, N),
    "ministry_count":       np.random.randint(1, 8, N),  # inter-ministry coordination
    "contractor_tier":      np.random.choice([1,2,3,4], N, p=[0.20,0.30,0.30,0.20]),
    "foreign_contractor":   np.random.binomial(1, 0.55, N),
    "design_complete_pct":  np.random.beta(5, 2, N),
    "land_acquired":        np.random.binomial(1, 0.78, N),
    "env_clearance":        np.random.binomial(1, 0.82, N),
    "funding_secured_pct":  np.random.beta(6, 2, N),
    "political_priority":   np.random.choice([1,2,3,4,5], N, p=[0.10,0.15,0.30,0.30,0.15]),
    "parliament_approval":  np.random.binomial(1, 0.70, N),
    "scope_changes_exp":    np.random.poisson(2, N).clip(0, 15),
    "labor_availability":   np.random.beta(4, 3, N),
    "summer_overlap_mo":    np.random.randint(0, 6, N),
    "ramadan_overlap":      np.random.randint(0, 2, N),
    "supply_chain_risk":    np.random.choice([1,2,3,4,5], N),
    "prev_contractor_delays":np.random.poisson(1.2, N).clip(0, 8),
    "oil_price_at_approval":np.random.uniform(40, 120, N),
    "election_year":        np.random.binomial(1, 0.20, N),  # Kuwait holds elections every ~4yr
})
df3["ptype_enc"] = le3p.transform(df3["project_type"])
delay_risk = (
    df3["scope_changes_exp"] * 0.8 +
    df3["ministry_count"] * 0.5 +
    df3["prev_contractor_delays"] * 1.2 +
    df3["summer_overlap_mo"] * 0.4 +
    df3["ramadan_overlap"] * 0.6 +
    (df3["land_acquired"] == 0).astype(int) * 2 +
    (df3["funding_secured_pct"] < 0.5).astype(int) * 2 +
    df3["election_year"] * 1 +
    (df3["contractor_tier"] == 4).astype(int) * 1.5 +
    (df3["oil_price_at_approval"] < 55).astype(int) * 1.5 +
    np.random.exponential(0.5, N)
)
df3["delayed"] = (delay_risk >= delay_risk.quantile(0.60)).astype(int)
feats3 = ["ptype_enc","budget_mkwd","planned_months","ministry_count","contractor_tier",
          "foreign_contractor","design_complete_pct","land_acquired","env_clearance",
          "funding_secured_pct","political_priority","parliament_approval",
          "scope_changes_exp","labor_availability","summer_overlap_mo","ramadan_overlap",
          "supply_chain_risk","prev_contractor_delays","oil_price_at_approval","election_year"]
X3, y3 = df3[feats3].fillna(0), df3["delayed"]
X3tr,X3te,y3tr,y3te = train_test_split(X3,y3,test_size=0.2,random_state=42)
m3,m3n,m3cv,m3a = automl_clf(X3tr,y3tr,"Project Delay")
y3p = m3.predict(X3te)
results["project_delay"] = {"type":"classification","task":"Government Project Delay Risk",
    "best_algo":m3n,"cv_acc":m3cv,"test_acc":round(float(accuracy_score(y3te,y3p)),4),
    "all_scores":m3a,"features":feats3,"feature_importance":feat_imp(m3,feats3),
    "classes":["On Time","Delayed"],"n_samples":N,
    "gcc_note":"Kuwait election cycles & inter-ministry coordination as unique delay drivers"}
models["project_delay"] = m3

# ════════════════════════════════════════════════════════════════
# MODEL 4 — PUBLIC SECTOR BUDGET FORECASTING
# ════════════════════════════════════════════════════════════════
print("\n[4/10] Public Sector Budget Forecasting")
df4 = pd.DataFrame({
    "oil_price_usd":         np.random.uniform(30, 130, N),
    "oil_production_mbpd":   np.random.normal(2.7, 0.3, N).clip(1.5, 3.5),
    "non_oil_revenue_pct":   np.random.beta(2, 8, N),
    "prev_year_spending":    np.random.lognormal(10, 0.4, N).clip(5000, 40000),
    "wages_bill_pct":        np.random.beta(4, 3, N),
    "subsidy_bill_pct":      np.random.beta(3, 5, N),
    "capex_pct":             np.random.beta(2, 5, N),
    "population_growth":     np.random.normal(2.5, 1, N).clip(-1, 6),
    "inflation_rate":        np.random.normal(3, 1.5, N).clip(0, 10),
    "gdp_growth":            np.random.normal(3.5, 2.5, N).clip(-5, 10),
    "sovereign_fund_assets": np.random.normal(700, 50, N).clip(500, 900),  # KIA ~$700B
    "debt_to_gdp":           np.random.beta(2, 8, N),
    "election_year":         np.random.binomial(1, 0.20, N),
    "war_risk_premium":      np.random.uniform(0, 0.05, N),
    "gcc_union_transfers":   np.random.lognormal(5, 0.8, N).clip(100, 5000),
    "us_fed_rate":           np.random.uniform(0, 6, N),  # KWD pegged to basket
    "china_demand_idx":      np.random.normal(100, 10, N).clip(70, 130),
    "diversification_score": np.random.uniform(1, 10, N),
    "subsidy_reform_pct":    np.random.beta(1, 5, N),
    "year":                  np.random.randint(2010, 2026, N),
})
df4["budget_bkwd"] = (
    df4["oil_price_usd"] * df4["oil_production_mbpd"] * 365 * 0.307 * 0.85 / 1000
    + df4["prev_year_spending"] * 0.03
    + df4["population_growth"] * 500
    + df4["election_year"] * 1500
    + np.random.normal(0, 800, N)
).clip(5000, 45000)
feats4 = ["oil_price_usd","oil_production_mbpd","non_oil_revenue_pct","prev_year_spending",
          "wages_bill_pct","subsidy_bill_pct","capex_pct","population_growth",
          "inflation_rate","gdp_growth","sovereign_fund_assets","debt_to_gdp",
          "election_year","war_risk_premium","gcc_union_transfers","us_fed_rate",
          "china_demand_idx","diversification_score","subsidy_reform_pct","year"]
X4, y4 = df4[feats4].fillna(0), df4["budget_bkwd"]
X4tr,X4te,y4tr,y4te = train_test_split(X4,y4,test_size=0.2,random_state=42)
m4,m4n,m4cv,m4a = automl_reg(X4tr,y4tr,"Budget Forecasting")
y4p = m4.predict(X4te)
results["budget_forecast"] = {"type":"regression","task":"Public Sector Budget Forecasting",
    "best_algo":m4n,"cv_r2":m4cv,"test_r2":round(float(r2_score(y4te,y4p)),4),
    "test_mae":round(float(mean_absolute_error(y4te,y4p)),4),
    "all_scores":m4a,"features":feats4,"feature_importance":feat_imp(m4,feats4),
    "target":"budget_bkwd (million KWD)","n_samples":N,
    "gcc_note":"KIA sovereign fund assets & oil price as primary Kuwait budget drivers"}
models["budget_forecast"] = m4

# ════════════════════════════════════════════════════════════════
# MODEL 5 — KUWAITIZATION / NATIONALIZATION RATE
# ════════════════════════════════════════════════════════════════
print("\n[5/10] Kuwaitization Rate Prediction")
industries = ["Banking","Insurance","Oil&Gas","Retail","Healthcare","Construction",
              "Hospitality","Technology","Education","Government"]
le5i = LabelEncoder().fit(industries)

df5 = pd.DataFrame({
    "industry":               np.random.choice(industries, N, p=[0.12,0.06,0.12,0.10,0.10,0.12,0.08,0.08,0.10,0.12]),
    "company_size":           np.random.choice([1,2,3,4,5], N, p=[0.20,0.25,0.25,0.20,0.10]),
    "quota_required_pct":     np.random.uniform(0.10, 0.60, N),
    "current_national_pct":   np.random.beta(3, 5, N),
    "avg_national_salary_kwd":np.random.normal(1500, 400, N).clip(500, 5000),
    "avg_expat_salary_kwd":   np.random.normal(600, 250, N).clip(150, 3000),
    "training_budget_pct":    np.random.beta(1, 8, N),
    "career_path_clarity":    np.random.choice([1,2,3,4,5], N),
    "management_nationality": np.random.binomial(1, 0.65, N),  # 1=Kuwaiti management
    "oil_price_usd":          np.random.uniform(40, 120, N),
    "economic_growth":        np.random.normal(3, 2, N).clip(-3, 8),
    "govt_incentive_score":   np.random.uniform(1, 10, N),
    "penalty_enforcement":    np.random.choice([1,2,3,4,5], N),
    "youth_unemployment":     np.random.normal(0.15, 0.05, N).clip(0.05, 0.35),
    "university_graduates_k": np.random.normal(8, 2, N).clip(3, 15),
    "skills_mismatch_score":  np.random.uniform(1, 10, N),
    "remote_work_available":  np.random.binomial(1, 0.40, N),
    "private_vs_govt_wage":   np.random.normal(0.6, 0.2, N).clip(0.2, 1.2),
    "wps_compliance":         np.random.beta(5, 2, N),
    "years_since_policy":     np.random.randint(0, 15, N),
})
df5["ind_enc"] = le5i.transform(df5["industry"])
df5["nationalization_rate"] = (
    df5["current_national_pct"] * 0.6
    + df5["govt_incentive_score"] * 0.02
    + df5["penalty_enforcement"] * 0.015
    + (df5["oil_price_usd"] / 100) * 0.05
    - df5["skills_mismatch_score"] * 0.01
    - df5["private_vs_govt_wage"] * 0.05
    + np.random.normal(0, 0.02, N)
).clip(0.05, 0.90)
feats5 = ["ind_enc","company_size","quota_required_pct","current_national_pct",
          "avg_national_salary_kwd","avg_expat_salary_kwd","training_budget_pct",
          "career_path_clarity","management_nationality","oil_price_usd",
          "economic_growth","govt_incentive_score","penalty_enforcement",
          "youth_unemployment","university_graduates_k","skills_mismatch_score",
          "remote_work_available","private_vs_govt_wage","wps_compliance","years_since_policy"]
X5, y5 = df5[feats5].fillna(0), df5["nationalization_rate"]
X5tr,X5te,y5tr,y5te = train_test_split(X5,y5,test_size=0.2,random_state=42)
m5,m5n,m5cv,m5a = automl_reg(X5tr,y5tr,"Kuwaitization Rate")
y5p = m5.predict(X5te)
results["kuwaitization"] = {"type":"regression","task":"Kuwaitization / Nationalization Rate",
    "best_algo":m5n,"cv_r2":m5cv,"test_r2":round(float(r2_score(y5te,y5p)),4),
    "test_mae":round(float(mean_absolute_error(y5te,y5p)),4),
    "all_scores":m5a,"features":feats5,"feature_importance":feat_imp(m5,feats5),
    "target":"nationalization_rate (0-1)","n_samples":N,
    "gcc_note":"Kuwaitization targets vary 10-60% by sector — critical compliance metric"}
models["kuwaitization"] = m5

# ════════════════════════════════════════════════════════════════
# MODEL 6 — EMPLOYEE PERFORMANCE PREDICTION
# ════════════════════════════════════════════════════════════════
print("\n[6/10] Employee Performance Prediction")
dept_types = ["Operations","Finance","HR","IT","Legal","Strategy","Communications","Audit","Procurement","Technical"]
le6d = LabelEncoder().fit(dept_types)

df6 = pd.DataFrame({
    "department":           np.random.choice(dept_types, N),
    "age":                  np.random.randint(22, 60, N),
    "education_level":      np.random.choice([1,2,3,4,5], N, p=[0.05,0.15,0.40,0.30,0.10]),
    "years_experience":     np.random.exponential(8, N).clip(0, 35),
    "years_in_role":        np.random.exponential(3, N).clip(0, 20),
    "is_national":          np.random.binomial(1, 0.55, N),
    "is_female":            np.random.binomial(1, 0.48, N),
    "training_hours_yr":    np.random.poisson(24, N).clip(0, 200),
    "certifications":       np.random.poisson(1.5, N).clip(0, 10),
    "absenteeism_rate":     np.random.beta(1, 10, N),
    "overtime_willingness": np.random.choice([1,2,3,4,5], N),
    "kpi_prev_year":        np.random.normal(75, 18, N).clip(20, 100),
    "peer_review_score":    np.random.normal(72, 15, N).clip(20, 100),
    "innovation_ideas":     np.random.poisson(2, N).clip(0, 15),
    "projects_completed":   np.random.poisson(5, N).clip(0, 30),
    "manager_quality":      np.random.choice([1,2,3,4,5], N),
    "team_size":            np.random.randint(1, 25, N),
    "remote_days":          np.random.poisson(1, N).clip(0, 5),
    "salary_satisfaction":  np.random.choice([1,2,3,4,5], N),
    "career_growth_score":  np.random.choice([1,2,3,4,5], N),
})
df6["dept_enc"] = le6d.transform(df6["department"])
df6["performance_score"] = (
    df6["kpi_prev_year"] * 0.35
    + df6["peer_review_score"] * 0.20
    + df6["training_hours_yr"] * 0.15
    + df6["certifications"] * 1.5
    + df6["innovation_ideas"] * 1.2
    + df6["manager_quality"] * 2
    + df6["career_growth_score"] * 1.5
    - df6["absenteeism_rate"] * 30
    + np.random.normal(0, 5, N)
).clip(20, 100)
feats6 = ["dept_enc","age","education_level","years_experience","years_in_role",
          "is_national","is_female","training_hours_yr","certifications",
          "absenteeism_rate","overtime_willingness","kpi_prev_year","peer_review_score",
          "innovation_ideas","projects_completed","manager_quality","team_size",
          "remote_days","salary_satisfaction","career_growth_score"]
X6, y6 = df6[feats6].fillna(0), df6["performance_score"]
X6tr,X6te,y6tr,y6te = train_test_split(X6,y6,test_size=0.2,random_state=42)
m6,m6n,m6cv,m6a = automl_reg(X6tr,y6tr,"Employee Performance")
y6p = m6.predict(X6te)
results["employee_performance"] = {"type":"regression","task":"Employee Performance Prediction",
    "best_algo":m6n,"cv_r2":m6cv,"test_r2":round(float(r2_score(y6te,y6p)),4),
    "test_mae":round(float(mean_absolute_error(y6te,y6p)),4),
    "all_scores":m6a,"features":feats6,"feature_importance":feat_imp(m6,feats6),
    "target":"performance_score (0-100)","n_samples":N,
    "gcc_note":"National vs expat performance dynamics key in GCC public sector"}
models["employee_performance"] = m6

# ════════════════════════════════════════════════════════════════
# MODEL 7 — PUBLIC SERVICES DEMAND FORECASTING
# ════════════════════════════════════════════════════════════════
print("\n[7/10] Public Services Demand Forecasting")
services = ["Passport","ID_Renewal","Driving_License","Birth_Certificate",
            "Marriage","Property_Registration","Business_License","Court","Police","Municipality"]
le7s = LabelEncoder().fit(services)

df7 = pd.DataFrame({
    "service_type":         np.random.choice(services, N),
    "month":                np.random.randint(1, 13, N),
    "day_of_week":          np.random.randint(0, 7, N),
    "is_ramadan":           np.random.binomial(1, 0.08, N),
    "is_eid":               np.random.binomial(1, 0.04, N),
    "is_summer":            np.random.binomial(1, 0.17, N),
    "population_k":         np.random.lognormal(5.5, 0.8, N).clip(50, 5000),
    "expat_pct":            np.random.uniform(0.30, 0.75, N),
    "online_pct":           np.random.beta(3, 4, N),  # digital adoption growing
    "staff_count":          np.random.randint(5, 200, N),
    "counter_count":        np.random.randint(2, 50, N),
    "avg_proc_time_min":    np.random.exponential(25, N).clip(5, 120),
    "backlog_prev_week":    np.random.lognormal(4, 1, N).clip(0, 2000),
    "weather_extreme":      np.random.binomial(1, 0.12, N),
    "policy_change":        np.random.binomial(1, 0.05, N),
    "news_event":           np.random.binomial(1, 0.08, N),
    "visa_expiry_season":   np.random.binomial(1, 0.20, N),
    "academic_year_start":  np.random.binomial(1, 0.10, N),
    "oil_price_env":        np.random.uniform(40, 120, N),
    "gdp_growth":           np.random.normal(3, 2, N).clip(-2, 8),
})
df7["stype_enc"] = le7s.transform(df7["service_type"])
df7["daily_demand"] = (
    df7["population_k"] * 0.5
    + df7["backlog_prev_week"] * 0.3
    - df7["online_pct"] * df7["population_k"] * 0.3
    + df7["is_ramadan"] * (-df7["population_k"] * 0.15)
    + df7["is_eid"] * (-df7["population_k"] * 0.40)
    + df7["policy_change"] * df7["population_k"] * 0.20
    + df7["visa_expiry_season"] * df7["population_k"] * 0.25
    + np.random.exponential(20, N)
).clip(5, 5000)
feats7 = ["stype_enc","month","day_of_week","is_ramadan","is_eid","is_summer",
          "population_k","expat_pct","online_pct","staff_count","counter_count",
          "avg_proc_time_min","backlog_prev_week","weather_extreme","policy_change",
          "news_event","visa_expiry_season","academic_year_start","oil_price_env","gdp_growth"]
X7, y7 = df7[feats7].fillna(0), df7["daily_demand"]
X7tr,X7te,y7tr,y7te = train_test_split(X7,y7,test_size=0.2,random_state=42)
m7,m7n,m7cv,m7a = automl_reg(X7tr,y7tr,"Public Services Demand")
y7p = m7.predict(X7te)
results["public_services"] = {"type":"regression","task":"Public Services Demand Forecasting",
    "best_algo":m7n,"cv_r2":m7cv,"test_r2":round(float(r2_score(y7te,y7p)),4),
    "test_mae":round(float(mean_absolute_error(y7te,y7p)),4),
    "all_scores":m7a,"features":feats7,"feature_importance":feat_imp(m7,feats7),
    "target":"daily_demand (transactions)","n_samples":N,
    "gcc_note":"Ramadan/Eid closures & visa expiry seasons drive GCC service demand spikes"}
models["public_services"] = m7

# ════════════════════════════════════════════════════════════════
# MODEL 8 — GOVERNMENT PROCUREMENT FRAUD DETECTION
# ════════════════════════════════════════════════════════════════
print("\n[8/10] Government Procurement Fraud Detection")
df8 = pd.DataFrame({
    "contract_value_mkwd":  np.random.lognormal(3, 2, N).clip(0.01, 500),
    "num_bidders":          np.random.poisson(4, N).clip(1, 25),
    "winning_margin_pct":   np.random.exponential(0.15, N).clip(0, 0.95),
    "single_source":        np.random.binomial(1, 0.18, N),
    "emergency_waiver":     np.random.binomial(1, 0.10, N),
    "vendor_age_years":     np.random.exponential(8, N).clip(0.1, 40),
    "vendor_prev_contracts":np.random.poisson(5, N).clip(0, 50),
    "vendor_complaints":    np.random.poisson(0.3, N).clip(0, 10),
    "contract_duration_mo": np.random.randint(1, 60, N),
    "payment_advance_pct":  np.random.beta(2, 5, N),
    "subcontracting_pct":   np.random.beta(2, 5, N),
    "related_party":        np.random.binomial(1, 0.08, N),
    "spec_tailored":        np.random.binomial(1, 0.12, N),  # specs written for 1 vendor
    "late_submission":      np.random.binomial(1, 0.15, N),
    "price_vs_estimate":    np.random.normal(1.05, 0.25, N).clip(0.3, 3.0),
    "committee_quorum":     np.random.binomial(1, 0.90, N),
    "audit_trail_score":    np.random.beta(5, 2, N),
    "vendor_nationality":   np.random.choice([1,2,3,4], N, p=[0.35,0.25,0.25,0.15]),
    "ministry_risk_score":  np.random.uniform(1, 10, N),
    "election_proximity":   np.random.binomial(1, 0.15, N),
})
fraud_score = (
    df8["single_source"] * 2.5 +
    df8["emergency_waiver"] * 2 +
    df8["related_party"] * 3 +
    df8["spec_tailored"] * 2.5 +
    (df8["num_bidders"] == 1).astype(int) * 2 +
    (df8["price_vs_estimate"] > 1.5).astype(int) * 1.5 +
    df8["vendor_complaints"] * 0.5 +
    (df8["audit_trail_score"] < 0.3).astype(int) * 1.5 +
    df8["election_proximity"] * 1 +
    np.random.exponential(0.3, N)
)
df8["fraud_flag"] = (fraud_score >= fraud_score.quantile(0.93)).astype(int)
feats8 = ["contract_value_mkwd","num_bidders","winning_margin_pct","single_source",
          "emergency_waiver","vendor_age_years","vendor_prev_contracts","vendor_complaints",
          "contract_duration_mo","payment_advance_pct","subcontracting_pct","related_party",
          "spec_tailored","late_submission","price_vs_estimate","committee_quorum",
          "audit_trail_score","vendor_nationality","ministry_risk_score","election_proximity"]
X8, y8 = df8[feats8].fillna(0), df8["fraud_flag"]
X8tr,X8te,y8tr,y8te = train_test_split(X8,y8,test_size=0.2,random_state=42)
m8,m8n,m8cv,m8a = automl_clf(X8tr,y8tr,"Procurement Fraud")
y8p = m8.predict(X8te)
results["procurement_fraud"] = {"type":"classification","task":"Government Procurement Fraud",
    "best_algo":m8n,"cv_acc":m8cv,"test_acc":round(float(accuracy_score(y8te,y8p)),4),
    "all_scores":m8a,"features":feats8,"feature_importance":feat_imp(m8,feats8),
    "classes":["Clean","Suspicious"],"n_samples":N,
    "gcc_note":"Single-source awards & election proximity as GCC-specific fraud signals"}
models["procurement_fraud"] = m8

# ════════════════════════════════════════════════════════════════
# MODEL 9 — SALARY BENCHMARKING & PAY GAP
# ════════════════════════════════════════════════════════════════
print("\n[9/10] Salary Benchmarking & Pay Gap")
job_families = ["Engineering","Finance","IT","HR","Legal","Operations","Medical",
                "Education","Administrative","Executive","Technical","Research"]
le9j = LabelEncoder().fit(job_families)
le9i = LabelEncoder().fit(industries)

df9 = pd.DataFrame({
    "job_family":           np.random.choice(job_families, N),
    "industry":             np.random.choice(industries, N),
    "seniority_level":      np.random.choice([1,2,3,4,5,6], N, p=[0.20,0.25,0.22,0.15,0.10,0.08]),
    "years_experience":     np.random.exponential(8, N).clip(0, 40),
    "education_level":      np.random.choice([1,2,3,4,5], N, p=[0.05,0.15,0.40,0.30,0.10]),
    "is_national":          np.random.binomial(1, 0.45, N),
    "is_female":            np.random.binomial(1, 0.42, N),
    "company_size":         np.random.choice([1,2,3,4,5], N),
    "sector":               np.random.choice([0,1], N, p=[0.55,0.45]),  # govt/private
    "certifications":       np.random.poisson(1.5, N).clip(0, 10),
    "bilingual":            np.random.binomial(1, 0.65, N),
    "performance_rating":   np.random.choice([1,2,3,4,5], N, p=[0.05,0.10,0.30,0.35,0.20]),
    "oil_price_env":        np.random.uniform(40, 120, N),
    "market_demand":        np.random.choice([1,2,3,4,5], N),
    "visa_sponsorship":     np.random.binomial(1, 0.55, N),
    "housing_allowance":    np.random.lognormal(5.5, 0.8, N).clip(0, 2000),
    "transport_allowance":  np.random.lognormal(4.5, 0.7, N).clip(0, 500),
    "years_in_gcc":         np.random.exponential(6, N).clip(0, 35),
    "negotiation_strength": np.random.choice([1,2,3,4,5], N),
    "remote_capable":       np.random.binomial(1, 0.40, N),
})
df9["jfam_enc"] = le9j.transform(df9["job_family"])
df9["ind_enc"]  = le9i.transform(df9["industry"])
df9["base_salary_kwd"] = (
    df9["seniority_level"] * 350
    + df9["years_experience"] * 45
    + df9["education_level"] * 120
    + df9["is_national"] * 400
    + df9["certifications"] * 60
    + df9["market_demand"] * 80
    + df9["performance_rating"] * 50
    + df9["oil_price_env"] * 2
    + np.random.normal(0, 150, N)
).clip(200, 8000)
feats9 = ["jfam_enc","ind_enc","seniority_level","years_experience","education_level",
          "is_national","is_female","company_size","sector","certifications","bilingual",
          "performance_rating","oil_price_env","market_demand","visa_sponsorship",
          "housing_allowance","transport_allowance","years_in_gcc","negotiation_strength","remote_capable"]
X9, y9 = df9[feats9].fillna(0), df9["base_salary_kwd"]
X9tr,X9te,y9tr,y9te = train_test_split(X9,y9,test_size=0.2,random_state=42)
m9,m9n,m9cv,m9a = automl_reg(X9tr,y9tr,"Salary Benchmarking")
y9p = m9.predict(X9te)
results["salary_benchmark"] = {"type":"regression","task":"Salary Benchmarking & Pay Gap",
    "best_algo":m9n,"cv_r2":m9cv,"test_r2":round(float(r2_score(y9te,y9p)),4),
    "test_mae":round(float(mean_absolute_error(y9te,y9p)),4),
    "all_scores":m9a,"features":feats9,"feature_importance":feat_imp(m9,feats9),
    "target":"base_salary_kwd","n_samples":N,
    "gcc_note":"National premium & oil price as unique GCC salary determinants"}
models["salary_benchmark"] = m9

# ════════════════════════════════════════════════════════════════
# MODEL 10 — WORKFORCE SUCCESSION PLANNING
# ════════════════════════════════════════════════════════════════
print("\n[10/10] Workforce Succession Planning")
df10 = pd.DataFrame({
    "age":                   np.random.randint(25, 62, N),
    "years_to_retirement":   np.random.randint(0, 35, N),
    "current_grade":         np.random.choice(range(1,11), N),
    "leadership_score":      np.random.normal(65, 20, N).clip(10, 100),
    "technical_score":       np.random.normal(70, 18, N).clip(10, 100),
    "strategic_score":       np.random.normal(60, 22, N).clip(10, 100),
    "communication_score":   np.random.normal(68, 18, N).clip(10, 100),
    "performance_3yr_avg":   np.random.normal(74, 15, N).clip(20, 100),
    "promotion_velocity":    np.random.exponential(0.3, N).clip(0, 2),  # promotions/yr
    "cross_dept_experience": np.random.poisson(1.5, N).clip(0, 8),
    "international_exp":     np.random.binomial(1, 0.28, N),
    "advanced_degree":       np.random.binomial(1, 0.35, N),
    "mentoring_others":      np.random.binomial(1, 0.40, N),
    "is_national":           np.random.binomial(1, 0.55, N),
    "is_female":             np.random.binomial(1, 0.48, N),
    "retention_risk":        np.random.choice([1,2,3,4,5], N),
    "critical_role":         np.random.binomial(1, 0.30, N),
    "deputy_experience":     np.random.binomial(1, 0.25, N),
    "training_completed":    np.random.poisson(8, N).clip(0, 40),
    "360_feedback_score":    np.random.normal(72, 16, N).clip(20, 100),
})
succession_score = (
    df10["leadership_score"] * 0.25
    + df10["strategic_score"] * 0.20
    + df10["performance_3yr_avg"] * 0.20
    + df10["promotion_velocity"] * 15
    + df10["deputy_experience"] * 8
    + df10["cross_dept_experience"] * 3
    + df10["international_exp"] * 5
    + df10["mentoring_others"] * 4
    + df10["advanced_degree"] * 4
    + df10["360_feedback_score"] * 0.10
    + np.random.normal(0, 5, N)
)
df10["succession_ready"] = pd.cut(succession_score, bins=3, labels=[0,1,2]).astype(int)
feats10 = ["age","years_to_retirement","current_grade","leadership_score","technical_score",
           "strategic_score","communication_score","performance_3yr_avg","promotion_velocity",
           "cross_dept_experience","international_exp","advanced_degree","mentoring_others",
           "is_national","is_female","retention_risk","critical_role","deputy_experience",
           "training_completed","360_feedback_score"]
X10, y10 = df10[feats10].fillna(0), df10["succession_ready"]
X10tr,X10te,y10tr,y10te = train_test_split(X10,y10,test_size=0.2,random_state=42)
m10,m10n,m10cv,m10a = automl_clf(X10tr,y10tr,"Succession Planning")
y10p = m10.predict(X10te)
results["succession_planning"] = {"type":"classification","task":"Workforce Succession Planning",
    "best_algo":m10n,"cv_acc":m10cv,"test_acc":round(float(accuracy_score(y10te,y10p)),4),
    "all_scores":m10a,"features":feats10,"feature_importance":feat_imp(m10,feats10),
    "classes":["Not Ready","Developing","Ready Now"],"n_samples":N,
    "gcc_note":"Retirement cliff risk & national leadership pipeline critical for Kuwait 2035"}
models["succession_planning"] = m10

# ════════════════════════════════════════════════════════════════
# MEGA DASHBOARD
# ════════════════════════════════════════════════════════════════
print("\nBuilding mega dashboard...")
plt.style.use("dark_background")
fig = plt.figure(figsize=(24, 32), facecolor=DARK)
fig.suptitle("GCC Government & HR AI — 10 Model Mega Batch\nAgenThink | Kuwait City",
             fontsize=24, fontweight="bold", color=GOLD, y=0.99)

gs = gridspec.GridSpec(5, 4, figure=fig, hspace=0.58, wspace=0.38,
                       top=0.96, bottom=0.03, left=0.06, right=0.97)

score_vals  = [r.get("test_r2", r.get("test_acc", 0)) for r in results.values()]
score_types = ["R²" if r["type"]=="regression" else "Acc" for r in results.values()]
algos_used  = [r["best_algo"] for r in results.values()]
pal = [TEAL,BLUE,RED,GOLD,GREEN,PURPLE,CYAN,ORANGE,TEAL,BLUE]
short = ["Civil\nAttrition","Visa\nApproval","Proj\nDelay","Budget\nForecast",
         "Kuwait-\nization","Employee\nPerf","Public\nSvc","Procure\nFraud",
         "Salary\nBench","Succession\nPlan"]

# ── Row 0: Master bar ─────────────────────────────────────────
ax0 = fig.add_subplot(gs[0, :])
ax0.set_facecolor("#111827")
bars = ax0.bar(range(10), score_vals, color=pal, alpha=0.85, edgecolor=DARK, linewidth=1.5)
for i,(bar,sv,st,al) in enumerate(zip(bars,score_vals,score_types,algos_used)):
    ax0.text(bar.get_x()+bar.get_width()/2, bar.get_height()+0.01,
             f"{st}:{sv:.3f}", ha="center", va="bottom", fontsize=8.5, color=WHITE, fontweight="bold")
ax0.set_xticks(range(10)); ax0.set_xticklabels(short, fontsize=9, color=WHITE)
ax0.set_ylim(0, 1.18); ax0.axhline(0.8, color=GREEN, linestyle="--", alpha=0.5)
ax0.text(9.5, 0.81, "80%", color=GREEN, fontsize=8)
ax0.set_title("AutoML Performance — All 10 GCC Government & HR Models", color=GOLD, fontsize=13, pad=10)
ax0.tick_params(colors=WHITE); ax0.spines[["top","right"]].set_visible(False)

# ── Row 1 col 0: Attrition by ministry ────────────────────────
ax1 = fig.add_subplot(gs[1, 0])
ax1.set_facecolor("#111827")
attr_min = df1.groupby("ministry")["will_leave"].mean().sort_values(ascending=True) * 100
bar_c1 = [RED if v > 25 else ORANGE if v > 15 else GREEN for v in attr_min.values]
ax1.barh(attr_min.index, attr_min.values, color=bar_c1, edgecolor=DARK, alpha=0.85)
ax1.set_xlabel("Attrition Rate (%)", color=WHITE, fontsize=8)
ax1.set_title(f"Attrition by Ministry\nAcc={results['civil_attrition']['test_acc']:.3f}", color=GOLD, fontsize=10)
ax1.tick_params(colors=WHITE, labelsize=7); ax1.spines[["top","right"]].set_visible(False)

# ── Row 1 col 1: Visa approval feature importance ─────────────
ax2 = fig.add_subplot(gs[1, 1])
ax2.set_facecolor("#111827")
fi2 = dict(sorted(results["visa_approval"]["feature_importance"].items(), key=lambda x: x[1])[-8:])
ax2.barh(list(fi2.keys()), list(fi2.values()), color=BLUE, edgecolor=DARK)
ax2.set_title(f"Visa Approval — Top Features\nAcc={results['visa_approval']['test_acc']:.3f}", color=GOLD, fontsize=10)
ax2.tick_params(colors=WHITE, labelsize=7); ax2.spines[["top","right"]].set_visible(False)

# ── Row 1 col 2: Project delay by type ────────────────────────
ax3 = fig.add_subplot(gs[1, 2])
ax3.set_facecolor("#111827")
delay_type = df3.groupby("project_type")["delayed"].mean().sort_values(ascending=True) * 100
bar_c3 = [RED if v > 65 else ORANGE if v > 55 else TEAL for v in delay_type.values]
ax3.barh(delay_type.index, delay_type.values, color=bar_c3, edgecolor=DARK, alpha=0.85)
ax3.set_xlabel("Delay Rate (%)", color=WHITE, fontsize=8)
ax3.set_title(f"Project Delay by Type\nAcc={results['project_delay']['test_acc']:.3f}", color=GOLD, fontsize=10)
ax3.tick_params(colors=WHITE, labelsize=8); ax3.spines[["top","right"]].set_visible(False)

# ── Row 1 col 3: Budget vs oil price ──────────────────────────
ax4 = fig.add_subplot(gs[1, 3])
ax4.set_facecolor("#111827")
ax4.scatter(df4["oil_price_usd"].values[:2000], df4["budget_bkwd"].values[:2000]/1000,
            alpha=0.3, s=8, color=GOLD)
ax4.set_xlabel("Oil Price (USD)", color=WHITE, fontsize=8)
ax4.set_ylabel("Budget (B KWD)", color=WHITE, fontsize=8)
ax4.set_title(f"Budget vs Oil Price\nR²={results['budget_forecast']['test_r2']:.3f}", color=GOLD, fontsize=10)
ax4.tick_params(colors=WHITE, labelsize=7); ax4.spines[["top","right"]].set_visible(False)

# ── Row 2 col 0: Kuwaitization by industry ────────────────────
ax5 = fig.add_subplot(gs[2, 0])
ax5.set_facecolor("#111827")
kwt_ind = df5.groupby("industry")["nationalization_rate"].mean().sort_values(ascending=True) * 100
ax5.barh(kwt_ind.index, kwt_ind.values, color=GREEN, edgecolor=DARK, alpha=0.85)
ax5.set_xlabel("Avg Nationalization Rate (%)", color=WHITE, fontsize=8)
ax5.set_title(f"Kuwaitization by Industry\nR²={results['kuwaitization']['test_r2']:.3f}", color=GOLD, fontsize=10)
ax5.tick_params(colors=WHITE, labelsize=8); ax5.spines[["top","right"]].set_visible(False)

# ── Row 2 col 1: Performance distribution ─────────────────────
ax6 = fig.add_subplot(gs[2, 1])
ax6.set_facecolor("#111827")
ax6.hist(df6["performance_score"], bins=40, color=PURPLE, alpha=0.75, edgecolor=DARK)
ax6.axvline(df6["performance_score"].mean(), color=GOLD, linestyle="--", linewidth=2, label=f"Mean={df6['performance_score'].mean():.1f}")
ax6.set_xlabel("Performance Score", color=WHITE, fontsize=8)
ax6.set_ylabel("Count", color=WHITE, fontsize=8)
ax6.set_title(f"Performance Distribution\nR²={results['employee_performance']['test_r2']:.3f}", color=GOLD, fontsize=10)
ax6.legend(fontsize=7, facecolor=DARK, labelcolor=WHITE)
ax6.tick_params(colors=WHITE, labelsize=7); ax6.spines[["top","right"]].set_visible(False)

# ── Row 2 col 2: Public services demand seasonality ───────────
ax7 = fig.add_subplot(gs[2, 2])
ax7.set_facecolor("#111827")
monthly_svc = df7.groupby("month")["daily_demand"].mean()
month_labels = ["J","F","M","A","M","J","J","A","S","O","N","D"]
bar_c7 = [GOLD if m in [3,4] else (RED if m in [7,8] else CYAN) for m in range(1,13)]
ax7.bar(month_labels, monthly_svc.reindex(range(1,13)).fillna(0), color=bar_c7, edgecolor=DARK, alpha=0.85)
ax7.set_ylabel("Avg Daily Demand", color=WHITE, fontsize=8)
ax7.set_title(f"Public Service Demand\nR²={results['public_services']['test_r2']:.3f}", color=GOLD, fontsize=10)
ax7.tick_params(colors=WHITE, labelsize=8); ax7.spines[["top","right"]].set_visible(False)

# ── Row 2 col 3: Procurement fraud feature importance ─────────
ax8 = fig.add_subplot(gs[2, 3])
ax8.set_facecolor("#111827")
fi8 = dict(sorted(results["procurement_fraud"]["feature_importance"].items(), key=lambda x: x[1])[-8:])
bar_c8 = [RED if v > 0.10 else ORANGE for v in fi8.values()]
ax8.barh(list(fi8.keys()), list(fi8.values()), color=bar_c8, edgecolor=DARK)
ax8.set_title(f"Procurement Fraud\nTop Features — Acc={results['procurement_fraud']['test_acc']:.3f}", color=GOLD, fontsize=10)
ax8.tick_params(colors=WHITE, labelsize=7); ax8.spines[["top","right"]].set_visible(False)

# ── Row 3: Salary benchmarking + succession ───────────────────
ax9 = fig.add_subplot(gs[3, :2])
ax9.set_facecolor("#111827")
salary_national = df9.groupby(["is_national","seniority_level"])["base_salary_kwd"].mean().unstack()
x_pos = np.arange(len(salary_national.columns))
if 0 in salary_national.index and 1 in salary_national.index:
    ax9.bar(x_pos - 0.2, salary_national.loc[0].values, width=0.38, label="Expat", color=BLUE, alpha=0.8, edgecolor=DARK)
    ax9.bar(x_pos + 0.2, salary_national.loc[1].values, width=0.38, label="National", color=GOLD, alpha=0.8, edgecolor=DARK)
ax9.set_xticks(x_pos)
ax9.set_xticklabels([f"L{i}" for i in salary_national.columns], color=WHITE, fontsize=9)
ax9.set_ylabel("Avg Salary (KWD)", color=WHITE, fontsize=9)
ax9.set_title(f"Salary: National vs Expat by Seniority\nR²={results['salary_benchmark']['test_r2']:.3f}", color=GOLD, fontsize=12)
ax9.legend(fontsize=9, facecolor=DARK, labelcolor=WHITE)
ax9.tick_params(colors=WHITE); ax9.spines[["top","right"]].set_visible(False)

ax10 = fig.add_subplot(gs[3, 2:])
ax10.set_facecolor("#111827")
succ_counts = [(df10["succession_ready"]==i).sum() for i in range(3)]
succ_labels = ["Not Ready", "Developing", "Ready Now"]
succ_colors = [RED, ORANGE, GREEN]
wedges, texts, autotexts = ax10.pie(succ_counts, labels=succ_labels, colors=succ_colors,
    autopct="%1.1f%%", startangle=90, textprops={"color":WHITE,"fontsize":10})
for at in autotexts: at.set_color(DARK); at.set_fontweight("bold")
ax10.set_title(f"Succession Readiness Distribution\nAcc={results['succession_planning']['test_acc']:.3f}", color=GOLD, fontsize=12)

# ── Row 4: Algorithm heatmap + summary ───────────────────────
ax11 = fig.add_subplot(gs[4, :3])
ax11.set_facecolor("#111827")
matrix = []
for key in results:
    r = results[key]
    row = [
        r["all_scores"].get("RandomForest", 0),
        r["all_scores"].get("GradientBoosting", 0),
        r["all_scores"].get("ExtraTrees", 0),
        r["all_scores"].get("LogisticRegression", r["all_scores"].get("Ridge", 0)),
        r["all_scores"].get("DecisionTree", 0),
    ]
    matrix.append([max(0.0, float(v)) for v in row])
matrix = np.array(matrix)
im11 = ax11.imshow(matrix, cmap="YlGn", aspect="auto", vmin=0.3, vmax=1.0)
for i in range(10):
    for j in range(5):
        ax11.text(j, i, f"{matrix[i,j]:.2f}", ha="center", va="center",
                  fontsize=8, color="black" if matrix[i,j]>0.65 else WHITE)
ax11.set_xticks(range(5)); ax11.set_xticklabels(["RF","GB","ET","LR","DT"], color=WHITE, fontsize=9)
ax11.set_yticks(range(10)); ax11.set_yticklabels(short, color=WHITE, fontsize=8)
ax11.set_title("AutoML Algorithm Competition — 10 Models × 5 Algorithms", color=GOLD, fontsize=12)
plt.colorbar(im11, ax=ax11, fraction=0.03)

ax12 = fig.add_subplot(gs[4, 3])
ax12.set_facecolor("#111827"); ax12.axis("off")
lines = [("GCC GOVT & HR AI", GOLD, 12, True),
         ("10 Models Trained", WHITE, 10, True), ("", WHITE, 8, False),
         (f"Regression:     {sum(1 for r in results.values() if r['type']=='regression')} models", TEAL, 9, False),
         (f"Classification: {sum(1 for r in results.values() if r['type']=='classification')} models", GREEN, 9, False),
         ("", WHITE, 8, False), ("Scores:", WHITE, 9, True)]
for key, r in results.items():
    s = r.get("test_r2", r.get("test_acc", 0))
    m = "R²" if r["type"]=="regression" else "Ac"
    c = GREEN if s >= 0.8 else ORANGE if s >= 0.5 else RED
    lines.append((f"{m}={s:.3f} {r['task'][:22]}", c, 7.5, False))
y_pos = 0.97
for txt, col, sz, bold in lines:
    ax12.text(0.03, y_pos, txt, transform=ax12.transAxes,
              fontsize=sz, color=col, fontweight="bold" if bold else "normal", va="top")
    y_pos -= 0.065

plt.savefig(f"{OUT}/gcc_government_hr_dashboard.png", dpi=150, bbox_inches="tight",
            facecolor=DARK, edgecolor="none")
plt.close()
print("  ✓ Dashboard saved")

# ── Save models & results ─────────────────────────────────────
print("\nSaving models...")
for name, model in models.items():
    joblib.dump(model, f"{OUT}/model_{name}.pkl")
with open(f"{OUT}/automl_results.json", "w") as f:
    json.dump(results, f, indent=2)

readme = """# GCC Government & HR AI — 10 Model Suite
**AgenThink | Kuwait City | github.com/agentthink**

Open-source AI for GCC public sector workforce and government operations.

## Models

| # | Model | Type | Score |
|---|-------|------|-------|
"""
for i,(key,r) in enumerate(results.items(),1):
    s = r.get("test_r2",r.get("test_acc",0))
    m = "R²" if r["type"]=="regression" else "Accuracy"
    readme += f"| {i} | {r['task']} | {r['type'].title()} | {m}: {s:.3f} |\n"

readme += """
## GCC-Specific Features
- **Kuwait election cycles** as government project delay driver
- **Kuwaitization quotas** (10-60% by sector) modeled per AAOIFI
- **Expat visa approval** with bilateral agreements & quota logic
- **KIA sovereign fund** assets in budget forecasting
- **National premium** in salary benchmarking
- **Retirement cliff risk** in civil service succession planning
- **Ramadan/Eid** impact on public service demand

## License
MIT — Free to use, modify, and deploy
"""
with open(f"{OUT}/README.md", "w") as f:
    f.write(readme)

# ── Final report ──────────────────────────────────────────────
print("\n" + "="*65)
print("  GCC GOVERNMENT & HR AI — FINAL REPORT")
print("="*65)
print(f"  {'Model':<38} {'Algorithm':<20} {'Score'}")
print(f"  {'-'*38} {'-'*20} {'-'*8}")
for key, r in results.items():
    s = r.get("test_r2", r.get("test_acc", 0))
    m = "R²  " if r["type"]=="regression" else "Acc "
    flag = "✅" if s >= 0.75 else "⚠️ " if s >= 0.50 else "📈"
    print(f"  {r['task']:<38} {r['best_algo']:<20} {m} {s:.4f}  {flag}")
print("="*65)
total = sum(1 for r in results.values() if r.get("test_r2",r.get("test_acc",0)) >= 0.75)
print(f"  {total}/10 models achieved ≥75% score")
print(f"  ✅  Complete — Ready for GitHub")
print("="*65)
