#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Deniz Ticareti, Liman Trafiği ve Hat Bağlantısallığı: WTO Mal Ticareti, Konteyner Liman Trafiği (TEU), UNCTAD Deniz Yolu Yükleri, Eurostat Liman Elleçlemesi, UNCTAD LSCI/PLSCI ve Kızıldeniz Krizi (2000–2026)
Maritime Trade, Port Traffic & Liner Connectivity: WTO Merchandise Trade, Container Port Traffic (TEU), UNCTAD Seaborne Cargo, Eurostat Port Handling, UNCTAD LSCI/PLSCI & the Red Sea Crisis (2000–2026)
==============================================================================
GOMD Python SDK — Gerçek veriyle yeniden üretilebilir vaka çalışması / Reproducible real-data case study
Google Colab Install: !pip install -q --upgrade gomd

Veri kaynakları / Data sources (hepsi GOMD sunucusundan canlı çekilir / all fetched live from the GOMD server):
  - wto_wb_merchandise_exports_usd, wto_wb_merchandise_imports_usd — WTO / Dünya Bankası
  - wb_port_traffic — Dünya Bankası konteyner liman trafiği (IS.SHP.GOOD.TU, TEU)
  - unctad_seaborne_loaded_total, unctad_seaborne_discharged_total — UNCTAD deniz yolu ticareti
  - eurostat_maritime_gross_freight_ths_t — Eurostat limanlarda elleçlenen brüt yük
  - UNCTAD_LSCI_MONTHLY, UNCTAD_PLSCI_QUARTERLY — UNCTAD hat taşımacılığı bağlantısallık endeksleri (ülke ve liman)
  - lpi_wb_overall_score — Dünya Bankası Lojistik Performans Endeksi
  - wb_ppi_transport_port_investment_usd — Dünya Bankası PPI (IE.PPI.TRAN.CD, tüm ulaştırma)

Not / Note: Bu betik sentetik veri üretmez. Bir seri sunucuda yoksa betik açık bir hata mesajıyla durur.
            This script never generates synthetic data. If a series is missing on the server, it stops with an explicit error.
"""

# ==============================================================================
# ADIM 0: GOMD Python SDK Kurulumu ve Canlı Veri Yardımcıları
# STEP 0: Install the GOMD Python SDK & Live Data Helpers
# ==============================================================================
import importlib
import os
import subprocess
import sys
import math
import json
from pathlib import Path
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

if hasattr(sys.stdout, "reconfigure"):
    try:
        sys.stdout.reconfigure(encoding="utf-8", errors="replace")
    except Exception:
        pass

_IN_COLAB = "google.colab" in sys.modules
_GOMD_WHEEL_URL = "https://gomd.pirireis.edu.tr/sdk/dist/gomd-2.0.1-py3-none-any.whl"
try:
    import gomd  # noqa: F401
    if _IN_COLAB:
        subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "--force-reinstall", "--no-cache-dir", _GOMD_WHEEL_URL])
except ImportError:
    subprocess.check_call([sys.executable, "-m", "pip", "install", "-q", "--force-reinstall", "--no-cache-dir", _GOMD_WHEEL_URL])

import gomd
for _mod_name in list(sys.modules.keys()):
    if _mod_name == "gomd" or _mod_name.startswith("gomd."):
        importlib.reload(sys.modules[_mod_name])
import gomd
from gomd import GOMDClient

client = GOMDClient("https://gomd.pirireis.edu.tr")


def fetch_gomd_records(indicator: str, entity: str, period_from=None, period_to=None, limit: int = 50000) -> pd.DataFrame:
    """
    GOMD sunucusundan bir göstergenin TEK bir varlık (ülke/havza) için ham kayıtlarını çeker.
    Yalnız istenen varlığın kayıtları tutulur; sunucu başka bir varlık döndürürse kullanılmaz.
    Returns a DataFrame with columns: period (str), value (float).
    """
    rows = client.get_series(indicator=indicator, entity=entity, period_from=period_from,
                             period_to=period_to, limit=limit, as_df=False)
    keep = [r for r in rows if str(r.get("entity_code") or "") == entity and r.get("value") is not None]
    if not keep:
        raise RuntimeError(f"GOMD sunucusunda veri yok: indicator={indicator}, entity={entity}")
    df = pd.DataFrame({"period": [str(r["period"]) for r in keep], "value": [float(r["value"]) for r in keep]})
    df = df.drop_duplicates("period").sort_values("period").reset_index(drop=True)
    print(f"📡 [GOMD] {indicator:<44} | {entity:<18} | N={len(df):<6} ({df['period'].iloc[0][:10]} – {df['period'].iloc[-1][:10]})")
    return df


def fetch_gomd_annual_series(indicator: str, entity: str, period_from: int = 1900, period_to: int = 2100,
                             how: str = "mean", min_count: int = 1) -> dict:
    """
    Yıllık seri döndürür: {yıl: değer}. Kayıtlar yıllık değilse (aylık/günlük) yıl içi ortalama alınır
    ve yalnız en az `min_count` kaydı olan yıllar tutulur. Returns {year: value}.
    """
    df = fetch_gomd_records(indicator, entity)
    df["year"] = df["period"].str[:4].astype(int)
    df = df[(df["year"] >= period_from) & (df["year"] <= period_to)]
    g = df.groupby("year")["value"]
    agg = g.mean() if how == "mean" else g.last()
    cnt = g.count()
    out = {int(y): float(v) for y, v in agg.items() if cnt[y] >= min_count}
    if not out:
        raise RuntimeError(f"Seçilen dönemde veri yok: indicator={indicator}, entity={entity}")
    return dict(sorted(out.items()))


def fmt_p(p: float) -> str:
    """p değerini okunur biçimde yazar / readable p-value."""
    return "<1e-6" if p < 1e-6 else f"{p:.4f}"


print(f"✅ GOMD Python SDK Sürümü / Version : v{gomd.__version__}")
print(f"🌐 Canlı Veri Sunucusu / Server     : {client.base_url}")
print(f"🏛️ Kurum / Institution              : Pîrî Reis Üniversitesi & T.C. Çevre, Şehircilik ve İklim Değişikliği Bakanlığı Çevre Yönetimi Genel Müdürlüğü — GOMD (COP31 Türkiye)")

# ==============================================================================
# ADIM 1: Türkiye dış ticareti, konteyner trafiği ve deniz yolu yük hacmi
# STEP 1: Türkiye trade, container port traffic & seaborne cargo volumes
# ==============================================================================
from gomd.stats import mann_kendall_sen, pettitt_changepoint, panel_fixed_effects, cointegration_eg_test

tur_exp = fetch_gomd_annual_series("wto_wb_merchandise_exports_usd", "TUR", 1970, 2025)
tur_imp = fetch_gomd_annual_series("wto_wb_merchandise_imports_usd", "TUR", 1970, 2025)
tur_teu = fetch_gomd_annual_series("wb_port_traffic", "TUR")                          # TEU (Dünya Bankası IS.SHP.GOOD.TU)
tur_load = fetch_gomd_annual_series("unctad_seaborne_loaded_total", "TUR")            # bin ton, deniz yoluyla yüklenen
tur_disc = fetch_gomd_annual_series("unctad_seaborne_discharged_total", "TUR")        # bin ton, deniz yoluyla boşaltılan
tur_gross = fetch_gomd_annual_series("eurostat_maritime_gross_freight_ths_t", "TUR")  # bin ton, limanlarda elleçlenen brüt yük

mk_teu = mann_kendall_sen(list(tur_teu.values()), t=list(tur_teu))
yt = sorted(tur_teu)
print(f"\n📦 Türkiye konteyner liman trafiği: {tur_teu[yt[0]]/1e6:.2f} milyon TEU ({yt[0]}) → {tur_teu[yt[-1]]/1e6:.2f} milyon TEU ({yt[-1]}); "
      f"Sen eğimi {mk_teu['theil_sen_slope']/1e6:+.3f} milyon TEU/yıl (p = {fmt_p(mk_teu['p_value'])})")
ys = sorted(set(tur_load) & set(tur_disc))
bal = {y: tur_load[y] / tur_disc[y] for y in ys}
print(f"⚓ Deniz yolu yükleme / boşaltma oranı: {bal[ys[0]]:.2f} ({ys[0]}) → {bal[ys[-1]]:.2f} ({ys[-1]})  (1'in altı: net ithalatçı tonaj)")
yg = sorted(tur_gross)
print(f"🏗️ Limanlarda elleçlenen brüt yük (Eurostat): {tur_gross[yg[0]]/1e3:,.0f} milyon t ({yg[0]}) → {tur_gross[yg[-1]]/1e3:,.0f} milyon t ({yg[-1]})")

ye = sorted(set(tur_teu) & set(tur_exp))
eg = cointegration_eg_test([tur_teu[y] / 1e6 for y in ye], [tur_exp[y] / 1e9 for y in ye])
print(f"🔗 Engle-Granger (TEU → ihracat, {len(ye)} yıl): eğim {eg['long_run_slope_beta']:+.1f} milyar USD / milyon TEU, "
      f"ADF t = {eg['engle_granger_adf_t_stat']:.2f} (%5 kritik {eg['critical_value_5pct']}; eşbütünleşik: {'evet' if eg['cointegrated_at_5pct'] else 'hayır'}). "
      f"Kısa seri: sonuç kesin değildir.")

# ==============================================================================
# ADIM 2: Hat taşımacılığı bağlantısallığı (UNCTAD LSCI) ve dış ticaret — 7 ülke paneli
# STEP 2: Liner shipping connectivity (UNCTAD LSCI) & trade — 7-country panel
# ==============================================================================
countries = ["TUR", "GRC", "ITA", "ESP", "EGY", "DEU", "NLD"]
QMONTHS = {"02", "05", "08", "11"}   # 2006–2022 arası yalnız bu aylar yayımlandı; yıllar karşılaştırılabilsin diye hep bu aylar kullanılır
lsci_m, lsci_a = {}, {}
rows, fe_rows = [], []
for iso in countries:
    d = fetch_gomd_records("UNCTAD_LSCI_MONTHLY", iso)
    d["date"] = pd.to_datetime(d["period"].str[:7])
    lsci_m[iso] = d
    q = d[d["period"].str[5:7].isin(QMONTHS)]
    g = q.groupby(q["period"].str[:4].astype(int))["value"]
    lsci_a[iso] = {int(y): float(v) for y, v in g.mean().items() if g.count()[y] == 4}
    ex = fetch_gomd_annual_series("wto_wb_merchandise_exports_usd", iso, 2006, 2025)
    im = fetch_gomd_annual_series("wto_wb_merchandise_imports_usd", iso, 2006, 2025)
    lpi = fetch_gomd_annual_series("lpi_wb_overall_score", iso)
    for y in sorted(set(ex) & set(im) & set(lsci_a[iso])):
        fe_rows.append({"iso": iso, "log_trade": math.log((ex[y] + im[y]) / 1e9), "log_lsci": math.log(lsci_a[iso][y])})
    yl = max(set(ex) & set(im))
    rows.append({"ISO": iso, f"Ticaret {yl} (milyar USD)": round((ex[yl] + im[yl]) / 1e9), "LSCI son ay": round(d["value"].iloc[-1], 1),
                 "Ay": d["period"].iloc[-1][:7], "LSCI 2019 ort.": round(lsci_a[iso].get(2019, float("nan")), 1),
                 f"LPI ({max(lpi)})": round(lpi[max(lpi)], 2)})
print("\n🚢 Bağlantısallık ve ticaret (LSCI birimi: UNCTAD, Şubat 2023 ortalaması = 100):")
print(pd.DataFrame(rows).to_string(index=False))
fe = panel_fixed_effects(fe_rows, "iso", "log_trade", "log_lsci")
print(f"📐 Ülke içi esneklik: LSCI %1 arttığında mal ticareti ≈ %{fe['beta_fe']:+.2f} (t = {fe['t_stat']:.2f}, ülke içi R² = {fe['r_squared_within']:.2f}, N = {fe['n_obs']}). "
      f"Ortak küresel eğilimler kontrol edilmemiştir; korelasyondur.")

# ==============================================================================
# ADIM 3: Liman düzeyinde bağlantısallık (UNCTAD PLSCI) — Türk limanları ve Kızıldeniz krizi
# STEP 3: Port-level connectivity (UNCTAD PLSCI) — Turkish ports & the Red Sea crisis
# ==============================================================================
PORTS = {
    "UNCTAD_PORT_TRPAM": "Ambarlı", "UNCTAD_PORT_TRMER": "Mersin", "UNCTAD_PORT_TRMPT": "Marport", "UNCTAD_PORT_TRKMX": "Kumport",
    "UNCTAD_PORT_TRALI": "Aliağa (Nemrut)", "UNCTAD_PORT_TRIZM": "İzmir", "UNCTAD_PORT_TRGEM": "Gemlik", "UNCTAD_PORT_TRYPO": "Yılport",
    "UNCTAD_PORT_TREYP": "Evyap", "UNCTAD_PORT_TRISK": "İskenderun",
    "UNCTAD_PORT_GRPIR": "Pire (Yunanistan)", "UNCTAD_PORT_EGPSD": "Port Said (Mısır)", "UNCTAD_PORT_ESALG": "Algeciras (İspanya)",
    "UNCTAD_PORT_ITGOA": "Cenova (İtalya)",
}
plsci = {}
for code in PORTS:
    d = fetch_gomd_records("UNCTAD_PLSCI_QUARTERLY", code)
    plsci[code] = pd.Series(d["value"].values, index=d["period"].str[:7])
PRE, CRISIS = "2023-10", "2024-07"       # Kızıldeniz'de ticari gemilere saldırılar Kasım 2023'te başladı
port_rows = []
for code, name in PORTS.items():
    s = plsci[code]
    port_rows.append({"Liman": name, "TR": code.startswith("UNCTAD_PORT_TR"), "2019-10": round(s.get("2019-10", float("nan")), 1), PRE: round(s.get(PRE, float("nan")), 1),
                      CRISIS: round(s.get(CRISIS, float("nan")), 1), f"Son ({s.index[-1]})": round(s.iloc[-1], 1),
                      "Kriz etkisi (%)": round(100 * (s.get(CRISIS) / s.get(PRE) - 1), 1) if s.get(PRE) and s.get(CRISIS) else None})
df_ports = pd.DataFrame(port_rows).sort_values(f"Son ({plsci['UNCTAD_PORT_TRPAM'].index[-1]})", ascending=False)
print("\n🏁 Liman bağlantısallığı (PLSCI; 2023 1. çeyrek ortalaması = 100):")
print(df_ports.drop(columns="TR").to_string(index=False))
print("ℹ️  'Kriz etkisi': 2023 4. çeyrek → 2024 3. çeyrek değişimi. Değişimi yalnız Kızıldeniz'e bağlamak için ek analiz gerekir.")

# Özel sektör katılımlı ulaştırma yatırımları (Dünya Bankası PPI, IE.PPI.TRAN.CD)
ppi = fetch_gomd_annual_series("wb_ppi_transport_port_investment_usd", "TUR")
print(f"\n💵 Türkiye, özel sektör katılımlı ulaştırma altyapısı yatırım taahhütleri (PPI): {len(ppi)} yılda kayıt var; "
      f"2015–2024 toplamı {sum(v for y, v in ppi.items() if 2015 <= y <= 2024)/1e9:.1f} milyar USD")
print("ℹ️  IE.PPI.TRAN.CD liman, havalimanı, karayolu ve demiryolunun TOPLAMIDIR; yalnız liman değildir. Kaydı olmayan yıl 'proje kaydı yok' demektir.")

# ==============================================================================
# ADIM 4: 4 Panelli Görselleştirme / 4-panel figure
# ==============================================================================
fig, axes = plt.subplots(2, 2, figsize=(14, 9.5), dpi=120)
fig.patch.set_facecolor("#071324")
for ax in axes.flat:
    ax.set_facecolor("#0b1d36"); ax.tick_params(colors="#cbd5e1")
    for sp in ax.spines.values():
        sp.set_color("#1e3a5f")
    ax.grid(alpha=0.18, color="#64748b")
leg = dict(facecolor="#0f172a", edgecolor="#334155", labelcolor="#f8fafc", fontsize=8)
pal = {"TUR": "#f43f5e", "GRC": "#38bdf8", "ITA": "#22c55e", "ESP": "#f59e0b", "EGY": "#fb923c", "DEU": "#e2e8f0", "NLD": "#a78bfa"}

ax1 = axes[0, 0]
ax1.bar(ye, [tur_teu[y] / 1e6 for y in ye], color="#38bdf8", alpha=0.82, label="Konteyner trafiği (milyon TEU)")
ax1.set_ylabel("milyon TEU", color="#38bdf8")
ax1t = ax1.twinx(); ax1t.plot(ye, [tur_exp[y] / 1e9 for y in ye], color="#22c55e", marker="o", lw=1.8, label="Mal ihracatı (milyar USD)")
ax1t.tick_params(colors="#86efac"); ax1t.set_ylabel("milyar USD", color="#22c55e")
ax1.set_title("A) Türkiye konteyner trafiği ve ihracat (Dünya Bankası, WTO)", color="#f8fafc", fontweight="bold")
h1, l1 = ax1.get_legend_handles_labels(); h2, l2 = ax1t.get_legend_handles_labels(); ax1.legend(h1 + h2, l1 + l2, loc="upper left", **leg)

ax2 = axes[0, 1]
ax2.plot(ys, [tur_load[y] / 1e3 for y in ys], color="#22c55e", lw=1.8, label="Deniz yoluyla yüklenen (UNCTAD)")
ax2.plot(ys, [tur_disc[y] / 1e3 for y in ys], color="#f43f5e", lw=1.8, label="Deniz yoluyla boşaltılan (UNCTAD)")
ax2.plot(yg, [tur_gross[y] / 1e3 for y in yg], color="#f59e0b", lw=1.8, ls="--", label="Limanlarda elleçlenen brüt yük (Eurostat)")
ax2.set_ylabel("milyon ton", color="#cbd5e1")
ax2.set_title("B) Türkiye deniz yolu yük hacmi", color="#f8fafc", fontweight="bold"); ax2.legend(**leg)

ax3 = axes[1, 0]
for iso in countries:
    d = lsci_m[iso]; ax3.plot(d["date"], d["value"], color=pal[iso], lw=1.4, label=iso)
ax3.axvline(pd.Timestamp("2023-11-01"), color="#e2e8f0", ls=":", lw=1.3, label="Kasım 2023: Kızıldeniz krizi")
ax3.set_ylabel("LSCI (Şubat 2023 ort. = 100)", color="#cbd5e1")
ax3.set_title("C) Hat taşımacılığı bağlantısallığı (UNCTAD LSCI)", color="#f8fafc", fontweight="bold"); ax3.legend(ncol=4, loc="upper center", **leg)
ax3.set_ylim(top=ax3.get_ylim()[1] * 1.12)

ax4 = axes[1, 1]
last_col = [c for c in df_ports.columns if c.startswith("Son")][0]
dp = df_ports.sort_values(last_col)
ax4.barh(dp["Liman"], dp[last_col], color=["#f43f5e" if tr else "#38bdf8" for tr in dp["TR"]])
ax4.set_xlabel(f"PLSCI, {last_col[5:-1]} (2023 1. çeyrek ort. = 100)", color="#cbd5e1")
ax4.set_title("D) Liman bağlantısallığı: Türk limanları (kırmızı) ve bölge limanları", color="#f8fafc", fontweight="bold")

fig.suptitle("GOMD — Vaka Çalışması 10: Deniz ticareti, liman trafiği ve hat bağlantısallığı (gerçek veri)", color="#ffffff", fontsize=12.5, fontweight="bold")
plt.tight_layout()
fig.savefig("cs10_maritime_trade_port_connectivity_logistics_panel.png", dpi=140, bbox_inches="tight", facecolor=fig.get_facecolor())
plt.show()
