"""
Compatibility script for computing game-specific correlation results.

Project structure after decompression:
    project_root/
    ├── code/
    ├── data/
    ├── figures/        # created automatically when figure scripts are run
    ├── README.md
    └── requirements.txt

This script reads:
    data/aco_results.xlsx
    data/civ6_results.xlsx
    data/tombraider_results.xlsx

Each input file must contain:
    Sheet1: basic emotion scores
    Sheet2: complex emotion labels
    Sheet3: historical-understanding labels

This script writes:
    data/aco_correlation_results.xlsx
    data/civ6_correlation_results.xlsx
    data/tombraider_correlation_results.xlsx
"""

from pathlib import Path

import numpy as np
import pandas as pd
from scipy.stats import pearsonr, pointbiserialr


BASE_DIR = Path(__file__).resolve().parents[1]
DATA_DIR = BASE_DIR / "data"


GAMES = {
    "aco": "aco_results.xlsx",
    "civ6": "civ6_results.xlsx",
    "tombraider": "tombraider_results.xlsx",
}


def safe_pointbiserial(binary_series: pd.Series, continuous_series: pd.Series):
    """Return point-biserial r and p; return NaN when one variable is constant."""
    pair = pd.concat([binary_series, continuous_series], axis=1)
    pair = pair.apply(pd.to_numeric, errors="coerce").dropna()

    if len(pair) < 3:
        return np.nan, np.nan

    if pair.iloc[:, 0].nunique() < 2 or pair.iloc[:, 1].nunique() < 2:
        return np.nan, np.nan

    return pointbiserialr(pair.iloc[:, 0], pair.iloc[:, 1])


def safe_pearson(series_a: pd.Series, series_b: pd.Series):
    """Return Pearson r and p; for two binary variables, this is equivalent to phi."""
    pair = pd.concat([series_a, series_b], axis=1)
    pair = pair.apply(pd.to_numeric, errors="coerce").dropna()

    if len(pair) < 3:
        return np.nan, np.nan

    if pair.iloc[:, 0].nunique() < 2 or pair.iloc[:, 1].nunique() < 2:
        return np.nan, np.nan

    return pearsonr(pair.iloc[:, 0], pair.iloc[:, 1])


def run_game(game_name: str, input_file: str) -> pd.DataFrame:
    file_path = DATA_DIR / input_file

    print(f"\n=== Processing {game_name} ===")
    print(f"Input file: {file_path}")

    basic_df = pd.read_excel(file_path, sheet_name="Sheet1")
    complex_df = pd.read_excel(file_path, sheet_name="Sheet2")
    history_df = pd.read_excel(file_path, sheet_name="Sheet3")

    basic_df.columns = basic_df.columns.str.strip()
    complex_df.columns = complex_df.columns.str.strip()
    history_df.columns = history_df.columns.str.strip()

    merged_df = basic_df.merge(complex_df, on="review_id").merge(
        history_df,
        on="review_id",
    )

    basic_cols = basic_df.columns.drop("review_id")
    complex_cols = complex_df.columns.drop("review_id")
    history_cols = history_df.columns.drop("review_id")

    results = []

    for b in basic_cols:
        for c in complex_cols:
            r, p = safe_pointbiserial(merged_df[c], merged_df[b])
            results.append((f"{b} ~ {c}", "Point-Biserial", r, p))

    for b in basic_cols:
        for h in history_cols:
            r, p = safe_pointbiserial(merged_df[h], merged_df[b])
            results.append((f"{b} ~ {h}", "Point-Biserial", r, p))

    for c in complex_cols:
        for h in history_cols:
            r, p = safe_pearson(merged_df[c], merged_df[h])
            results.append((f"{c} ~ {h}", "Pearson (binary/phi)", r, p))

    correlation_df = pd.DataFrame(
        results,
        columns=["Comparison", "Method", "Correlation Coefficient", "p-value"],
    )

    output_file = DATA_DIR / f"{game_name}_correlation_results.xlsx"
    correlation_df.to_excel(output_file, index=False)

    print(f"Saved: {output_file}")
    print(f"Number of correlations: {len(correlation_df)}")

    return correlation_df


if __name__ == "__main__":
    for game, input_xlsx in GAMES.items():
        run_game(game, input_xlsx)

    print("\nAll game-specific correlation analyses completed.")
