#!/usr/bin/env python3
"""Direction 3: Migration ↔ Anti-Democratic Overlap Analysis.

Tests the hypothesis that migration is the primary vehicle for anti-democratic
rhetoric in right-wing parliamentary motions.
"""

from __future__ import annotations

import logging
import sys
from pathlib import Path

import duckdb

from analysis.right_wing.common import ROOT, _conn

if str(ROOT) not in sys.path:
    sys.path.insert(0, str(ROOT))

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
logger = logging.getLogger(__name__)


def print_section(title: str) -> None:
    print(f"\n{'=' * 70}")
    print(f"  {title}")
    print(f"{'=' * 70}")


def analyze_overlap() -> None:
    """1. Quantify overlap: what % of high-extremity motions are migration-related?"""
    print_section("1. OVERLAP QUANTIFICATION")

    conn = _conn()

    # High-extremity buckets by category
    rows = conn.execute("""
        SELECT
            r.category,
            COUNT(*) as total,
            COUNT(*) FILTER (WHERE e.text_score >= 3.5) as high_ext,
            COUNT(*) FILTER (WHERE e.text_score >= 4.0) as very_high_ext,
            COUNT(*) FILTER (WHERE e.text_score >= 5.0) as max_ext,
            ROUND(AVG(e.text_score), 2) as avg_ext,
            ROUND(AVG(s.text_score), 3) as avg_sent
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category IS NOT NULL
        GROUP BY r.category
        ORDER BY high_ext DESC
    """).fetchall()

    print(f"\n{'Category':<25} {'Total':>6} {'≥3.5':>6} {'≥4.0':>6} {'=5.0':>6} {'AvgExt':>7} {'AvgSent':>8}")
    print("-" * 70)
    total_high = 0
    total_very_high = 0
    total_max = 0
    for row in rows:
        cat, tot, h, vh, mx, avg_e, avg_s = row
        total_high += h
        total_very_high += vh
        total_max += mx
        print(f"{cat:<25} {tot:>6} {h:>6} {vh:>6} {mx:>6} {avg_e:>7.2f} {avg_s:>+8.3f}")

    # Migration share of high-extremity
    mig_high = conn.execute("""
        SELECT COUNT(*) FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        WHERE r.category = 'asiel/vreemdelingen' AND e.text_score >= 3.5
    """).fetchone()[0]

    mig_very_high = conn.execute("""
        SELECT COUNT(*) FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        WHERE r.category = 'asiel/vreemdelingen' AND e.text_score >= 4.0
    """).fetchone()[0]

    mig_max = conn.execute("""
        SELECT COUNT(*) FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        WHERE r.category = 'asiel/vreemdelingen' AND e.text_score >= 5.0
    """).fetchone()[0]

    print(f"\n--- Migration share of high-extremity motions ---")
    print(f"  Migration motions ≥3.5 extremity: {mig_high} / {total_high} ({100*mig_high/total_high:.1f}%)")
    print(f"  Migration motions ≥4.0 extremity: {mig_very_high} / {total_very_high} ({100*mig_very_high/total_very_high:.1f}%)")
    print(f"  Migration motions =5.0 extremity: {mig_max} / {total_max} ({100*mig_max/total_max:.1f}%)")

    # Category breakdown of ≥4.0 motions
    print(f"\n--- Category breakdown of ≥4.0 extremity motions ---")
    rows = conn.execute("""
        SELECT r.category, COUNT(*) as cnt,
               ROUND(100.0 * COUNT(*) / SUM(COUNT(*)) OVER (), 1) as pct
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        WHERE e.text_score >= 4.0
        GROUP BY r.category
        ORDER BY cnt DESC
    """).fetchall()
    for cat, cnt, pct in rows:
        print(f"  {cat:<25} {cnt:>3} ({pct:>5.1f}%)")

    conn.close()


def analyze_party_strategy() -> None:
    """2. Which parties file extreme migration motions?"""
    print_section("2. PARTY STRATEGY: EXTREME MIGRATION MOTIONS BY PARTY")

    conn = _conn()

    # Need to join with motions and mp_votes to get the submitting MP's party
    # The title prefix tells us who submitted: "Motie van het lid <name>" or "Motie van de leden <name> en <name>"
    # We'll use mp_metadata to map MP names to parties

    # First, extract the lead MP name from the title
    print("\n--- Top 20 highest-extremity migration motions with lead MP ---")
    rows = conn.execute("""
        SELECT r.title, r.year, e.text_score, e.layman_score,
               s.text_score, s.layman_score
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category = 'asiel/vreemdelingen'
        ORDER BY e.text_score DESC, r.year DESC
        LIMIT 20
    """).fetchall()

    for title, year, ext_t, ext_l, sent_t, sent_l in rows:
        sent_t_str = f"{sent_t:+.2f}" if sent_t is not None else "  N/A"
        sent_l_str = f"{sent_l:+.2f}" if sent_l is not None else "  N/A"
        print(f"  [{year}] ext={ext_t:.1f}/{ext_l:.1f} sent={sent_t_str}/{sent_l_str} {title[:65]}")

    # Party breakdown of migration motions by extremity bucket
    # We need to parse the title to get the MP name, then map to party via mp_metadata
    # The pattern is: "Motie van het lid <name>" or "Motie van de leden <name> en <name>"
    # or "Gewijzigde motie van ..."

    print("\n--- Party attribution of migration motions (by keyword in title) ---")
    # Use a heuristic: known MPs from the extreme list
    mp_parties = {
        "Wilders": "PVV", "Baudet": "FVD", "Kops": "PVV", "Markuszower": "PVV",
        "Vondeling": "PVV", "Boon": "PVV", "Eerdmans": "JA21", "Léon de Jong": "PVV",
        "Van Haga": "BVNL", "Smolders": "PVV", "Van der Plas": "BBB",
        "Van Zanten": "SGP", "Ceder": "CU", "Faber": "PVV", "Ram": "PVV",
        "Rajkowski": "PVV", "Boomsma": "BBB",
    }

    for mp, party in mp_parties.items():
        cnt = conn.execute(f"""
            SELECT COUNT(*) FROM right_wing_motions r
            JOIN extremity_scores e ON r.motion_id = e.motion_id
            WHERE r.category = 'asiel/vreemdelingen'
              AND r.title LIKE '%{mp}%'
        """).fetchone()[0]
        avg_ext = conn.execute(f"""
            SELECT ROUND(AVG(e.text_score), 2) FROM right_wing_motions r
            JOIN extremity_scores e ON r.motion_id = e.motion_id
            WHERE r.category = 'asiel/vreemdelingen'
              AND r.title LIKE '%{mp}%'
        """).fetchone()[0]
        high_cnt = conn.execute(f"""
            SELECT COUNT(*) FROM right_wing_motions r
            JOIN extremity_scores e ON r.motion_id = e.motion_id
            WHERE r.category = 'asiel/vreemdelingen'
              AND r.title LIKE '%{mp}%'
              AND e.text_score >= 4.0
        """).fetchone()[0]
        if cnt > 0:
            print(f"  {mp:<15} ({party:<5}) | n={cnt:>3} | avg_ext={avg_ext:>4.2f} | ≥4.0={high_cnt}")

    # Overall party shares among migration motions (all)
    print("\n--- Overall party share of migration motions (title keyword heuristic) ---")
    party_keywords = {
        "PVV": ["Wilders", "Kops", "Markuszower", "Vondeling", "Boon", "Smolders", "Ram", "Rajkowski", "Faber"],
        "FVD": ["Baudet"],
        "JA21": ["Eerdmans"],
        "BBB": ["Van der Plas", "Boomsma"],
        "SGP": ["Van Zanten"],
        "CU": ["Ceder"],
        "BVNL": ["Van Haga"],
    }

    total_migration = conn.execute("""
        SELECT COUNT(*) FROM right_wing_motions
        WHERE category = 'asiel/vreemdelingen'
    """).fetchone()[0]

    for party, mps in party_keywords.items():
        conditions = " OR ".join([f"title LIKE '%{mp}%'" for mp in mps])
        cnt = conn.execute(f"""
            SELECT COUNT(*) FROM right_wing_motions
            WHERE category = 'asiel/vreemdelingen' AND ({conditions})
        """).fetchone()[0]
        pct = 100 * cnt / total_migration if total_migration else 0
        print(f"  {party:<5} | {cnt:>3} / {total_migration} ({pct:>5.1f}%)")

    conn.close()


def analyze_framing_shift() -> None:
    """3. Compare 2018-2020 vs 2023-2025 migration motions."""
    print_section("3. FRAMING SHIFT: 2018-2020 VS 2023-2025")

    conn = _conn()

    periods = [
        ("2018-2020", "2018", "2020"),
        ("2021-2022", "2021", "2022"),
        ("2023-2025", "2023", "2025"),
        ("2026", "2026", "2026"),
    ]

    print(f"\n{'Period':<12} {'Count':>6} {'AvgExt':>7} {'AvgSent':>8} {'≥4.0':>6} {'=5.0':>6}")
    print("-" * 55)
    for label, start, end in periods:
        if start == end:
            where = f"r.year = {start}"
        else:
            where = f"r.year BETWEEN {start} AND {end}"

        row = conn.execute(f"""
            SELECT
                COUNT(*),
                ROUND(AVG(e.text_score), 2),
                ROUND(AVG(s.text_score), 3),
                COUNT(*) FILTER (WHERE e.text_score >= 4.0),
                COUNT(*) FILTER (WHERE e.text_score >= 5.0)
            FROM right_wing_motions r
            JOIN extremity_scores e ON r.motion_id = e.motion_id
            LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
            WHERE r.category = 'asiel/vreemdelingen' AND {where}
        """).fetchone()

        cnt, avg_e, avg_s, high, max_e = row
        avg_s_str = f"{avg_s:+.3f}" if avg_s is not None else "   N/A"
        print(f"{label:<12} {cnt:>6} {avg_e:>7.2f} {avg_s_str:>8} {high:>6} {max_e:>6}")

    # Sample titles from each period
    print("\n--- Sample titles: 2018-2020 (early period) ---")
    rows = conn.execute("""
        SELECT r.title, e.text_score, s.text_score
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category = 'asiel/vreemdelingen'
          AND r.year BETWEEN 2018 AND 2020
        ORDER BY e.text_score DESC
        LIMIT 8
    """).fetchall()
    for title, ext, sent in rows:
        sent_str = f"{sent:+.2f}" if sent is not None else "N/A"
        print(f"  ext={ext:.1f} sent={sent_str:>6} {title[:60]}")

    print("\n--- Sample titles: 2023-2025 (recent period) ---")
    rows = conn.execute("""
        SELECT r.title, e.text_score, s.text_score
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category = 'asiel/vreemdelingen'
          AND r.year BETWEEN 2023 AND 2025
        ORDER BY e.text_score DESC
        LIMIT 8
    """).fetchall()
    for title, ext, sent in rows:
        sent_str = f"{sent:+.2f}" if sent is not None else "N/A"
        print(f"  ext={ext:.1f} sent={sent_str:>6} {title[:60]}")

    # Keyword evolution
    print("\n--- Keyword themes in titles by period ---")
    themes = {
        "asiel": ["asiel", "asielzoeker", "asielaanvraag"],
        "immigrant": ["immigrant", "immigratie"],
        "vreemdeling": ["vreemdeling", "vreemdelingen"],
        "opvang": ["opvang", "opvangplaats", "opvangcrisis"],
        "terugkeer": ["terugkeer", "uitzetting", "uitschrijving", "afschiet"],
        "grenzen": ["grens", "grenzen", "schengen"],
        "denaturalisatie": ["denaturalisatie", "nationaliteit", "paspoort"],
        "moslim/islam": ["islam", "moslim", "imam"],
        "syrische": ["syrische", "syrie", "syrier"],
    }

    for label, start, end in [("2018-2020", "2018", "2020"), ("2023-2025", "2023", "2025")]:
        print(f"\n  Period: {label}")
        for theme, kws in themes.items():
            conditions = " OR ".join([f"LOWER(title) LIKE '%{kw}%'" for kw in kws])
            cnt = conn.execute(f"""
                SELECT COUNT(*) FROM right_wing_motions
                WHERE category = 'asiel/vreemdelingen'
                  AND year BETWEEN {start} AND {end}
                  AND ({conditions})
            """).fetchone()[0]
            print(f"    {theme:<18} {cnt:>3}")

    conn.close()


def analyze_cross_category() -> None:
    """4. Cross-category migration-adjacent analysis."""
    print_section("4. CROSS-CATEGORY MIGRATION-ADJACENT ANALYSIS")

    conn = _conn()

    # Find migration-adjacent motions in other categories (by title keywords)
    mig_keywords = ["asiel", "asielzoeker", "vreemdeling", "immigrant", "immigratie",
                    "opvang", "terugkeer", "uitzetting", "schengen", "grens", "syrische"]
    conditions = " OR ".join([f"LOWER(title) LIKE '%{kw}%'" for kw in mig_keywords])

    print(f"\n--- Migration-adjacent motions outside 'asiel/vreemdelingen' category ---")
    rows = conn.execute(f"""
        SELECT r.category, COUNT(*) as cnt,
               ROUND(AVG(e.text_score), 2) as avg_ext,
               ROUND(AVG(s.text_score), 3) as avg_sent
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category != 'asiel/vreemdelingen'
          AND ({conditions})
        GROUP BY r.category
        ORDER BY cnt DESC
    """).fetchall()

    total_adjacent = sum(r[1] for r in rows)
    print(f"  Total migration-adjacent in other categories: {total_adjacent}")
    print(f"\n  {'Category':<25} {'Count':>6} {'AvgExt':>7} {'AvgSent':>8}")
    print("  " + "-" * 50)
    for cat, cnt, avg_e, avg_s in rows:
        avg_s_str = f"{avg_s:+.3f}" if avg_s is not None else "   N/A"
        print(f"  {cat:<25} {cnt:>6} {avg_e:>7.2f} {avg_s_str:>8}")

    # Specific high-extremity migration-adjacent outside migration category
    print(f"\n--- High-extremity (≥4.0) migration-adjacent outside migration category ---")
    rows = conn.execute(f"""
        SELECT r.title, r.category, r.year, e.text_score, s.text_score
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        LEFT JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category != 'asiel/vreemdelingen'
          AND e.text_score >= 4.0
          AND ({conditions})
        ORDER BY e.text_score DESC, r.year DESC
        LIMIT 15
    """).fetchall()

    for title, cat, year, ext, sent in rows:
        sent_str = f"{sent:+.2f}" if sent is not None else "N/A"
        print(f"  [{year}] ext={ext:.1f} sent={sent_str:>6} [{cat}] {title[:55]}")

    # Combined migration + migration-adjacent totals
    mig_total = conn.execute("""
        SELECT COUNT(*) FROM right_wing_motions
        WHERE category = 'asiel/vreemdelingen'
    """).fetchone()[0]

    print(f"\n--- Combined migration scope ---")
    print(f"  Pure migration category:     {mig_total:>3} motions")
    print(f"  Migration-adjacent (other):  {total_adjacent:>3} motions")
    print(f"  Total migration-relevant:    {mig_total + total_adjacent:>3} motions")
    print(f"  Share of all right-wing:     {100*(mig_total + total_adjacent)/2986:.1f}%")

    conn.close()


def analyze_sentiment_divergence() -> None:
    """5. Sentiment divergence: why is migration the only negative-sentiment category?"""
    print_section("5. SENTIMENT DIVERGENCE: MIGRATION VS ALL OTHER CATEGORIES")

    conn = _conn()

    print("\n--- Sentiment comparison (raw text score) ---")
    rows = conn.execute("""
        SELECT
            r.category,
            COUNT(*) as cnt,
            ROUND(AVG(s.text_score), 3) as avg_sent_text,
            ROUND(AVG(s.layman_score), 3) as avg_sent_layman,
            ROUND(AVG(s.layman_score - s.text_score), 3) as layman_minus_text
        FROM right_wing_motions r
        JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category IS NOT NULL
        GROUP BY r.category
        ORDER BY avg_sent_text ASC
    """).fetchall()

    print(f"  {'Category':<25} {'Count':>6} {'Text':>7} {'Layman':>7} {'L-T':>6}")
    print("  " + "-" * 55)
    for cat, cnt, st, sl, diff in rows:
        print(f"  {cat:<25} {cnt:>6} {st:>+7.3f} {sl:>+7.3f} {diff:>+6.3f}")

    # Migration-specific sentiment by extremity bucket
    print("\n--- Migration sentiment by extremity bucket ---")
    rows = conn.execute("""
        SELECT
            CASE
                WHEN e.text_score < 2.0 THEN '1-2 (Low)'
                WHEN e.text_score < 3.0 THEN '2-3 (Moderate)'
                WHEN e.text_score < 4.0 THEN '3-4 (High)'
                ELSE '4-5 (Very High)'
            END as bucket,
            COUNT(*) as cnt,
            ROUND(AVG(s.text_score), 3) as avg_sent_text,
            ROUND(AVG(s.layman_score), 3) as avg_sent_layman
        FROM right_wing_motions r
        JOIN extremity_scores e ON r.motion_id = e.motion_id
        JOIN sentiment_scores s ON r.motion_id = s.motion_id
        WHERE r.category = 'asiel/vreemdelingen'
        GROUP BY bucket
        ORDER BY bucket
    """).fetchall()

    for bucket, cnt, st, sl in rows:
        print(f"  {bucket:<18} n={cnt:>3}  text={st:>+.3f}  layman={sl:>+.3f}")

    conn.close()


def main() -> None:
    print("=" * 70)
    print("  DIRECTION 3: MIGRATION ↔ ANTI-DEMOCRATIC OVERLAP ANALYSIS")
    print("=" * 70)

    analyze_overlap()
    analyze_party_strategy()
    analyze_framing_shift()
    analyze_cross_category()
    analyze_sentiment_divergence()

    print("\n" + "=" * 70)
    print("  ANALYSIS COMPLETE")
    print("=" * 70)


if __name__ == "__main__":
    main()
