"""Profils horaires/saisonniers liés à l'irradiance et aux cycles diurnes."""

from __future__ import annotations

from pathlib import Path
from typing import Sequence

import matplotlib.dates as mdates
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

from .base import export_plot_dataset
from meteo.analysis import DiurnalCycleStats
from meteo.variables import Variable

__all__ = ['plot_diurnal_cycle', 'plot_seasonal_hourly_profiles', 'plot_daylight_hours']


def plot_diurnal_cycle(
    stats: DiurnalCycleStats,
    variables: Sequence[Variable],
    output_path: str | Path,
) -> Path:
    """
    Trace les cycles diurnes moyens (moyenne/médiane + quantiles).
    """
    output_path = Path(output_path)
    output_path.parent.mkdir(parents=True, exist_ok=True)

    export_plot_dataset(
        {
            "mean": stats.mean,
            "median": stats.median,
            "quantile_low": stats.quantile_low,
            "quantile_high": stats.quantile_high,
        },
        output_path,
    )

    hours = stats.mean.index.to_numpy(dtype=float)
    n_vars = len(variables)
    fig, axes = plt.subplots(n_vars, 1, figsize=(10, 3 * n_vars), sharex=True)
    if n_vars == 1:
        axes = [axes]

    for ax, var in zip(axes, variables):
        col = var.column
        ax.plot(hours, stats.mean[col], label="Moyenne", color="tab:blue")
        ax.plot(hours, stats.median[col], label="Médiane", color="tab:orange", linestyle="--")
        if stats.quantile_low is not None and stats.quantile_high is not None:
            ax.fill_between(
                hours,
                stats.quantile_low[col],
                stats.quantile_high[col],
                color="tab:blue",
                alpha=0.15,
                label=(
                    f"Quantiles {int(stats.quantile_low_level * 100)}–{int(stats.quantile_high_level * 100)}%"
                    if stats.quantile_low_level is not None and stats.quantile_high_level is not None
                    else "Quantiles"
                ),
            )
        ylabel = f"{var.label} ({var.unit})" if var.unit else var.label
        ax.set_ylabel(ylabel)
        ax.grid(True, linestyle=":", alpha=0.5)

    axes[-1].set_xlabel("Heure locale")
    axes[0].legend(loc="upper right")
    axes[-1].set_xticks(range(0, 24, 2))
    axes[-1].set_xlim(0, 23)
    fig.suptitle("Cycle diurne moyen")
    fig.tight_layout(rect=[0, 0, 1, 0.97])
    fig.savefig(output_path, dpi=150)
    plt.close(fig)
    return output_path.resolve()

def plot_seasonal_hourly_profiles(
    profile_df: pd.DataFrame,
    output_path: str | Path,
    *,
    title: str,
    ylabel: str,
) -> Path:
    """
    Courbes moyennes par heure pour chaque saison.
    """
    output_path = Path(output_path)
    output_path.parent.mkdir(parents=True, exist_ok=True)

    if profile_df.empty or profile_df.isna().all().all():
        fig, ax = plt.subplots()
        ax.text(0.5, 0.5, "Pas de profil saisonnier disponible.", ha="center", va="center")
        ax.set_axis_off()
        fig.savefig(output_path, dpi=150, bbox_inches="tight")
        plt.close(fig)
        return output_path.resolve()

    export_plot_dataset(profile_df, output_path)

    hours = profile_df.index.to_numpy(dtype=float)
    fig, ax = plt.subplots(figsize=(10, 4))
    colors = plt.get_cmap("turbo")(np.linspace(0.1, 0.9, profile_df.shape[1]))
    for color, season in zip(colors, profile_df.columns):
        ax.plot(hours, profile_df[season], label=season.capitalize(), color=color)

    ax.set_xlabel("Heure locale")
    ax.set_ylabel(ylabel)
    ax.set_title(title)
    ax.grid(True, linestyle=":", alpha=0.5)
    ax.legend()
    fig.tight_layout()
    fig.savefig(output_path, dpi=150)
    plt.close(fig)
    return output_path.resolve()

def plot_daylight_hours(
    monthly_series: pd.Series,
    output_path: str | Path,
    *,
    title: str = "Durée moyenne de luminosité (> seuil)",
) -> Path:
    """
    Représente la durée moyenne quotidienne de luminosité par mois.
    """
    output_path = Path(output_path)
    output_path.parent.mkdir(parents=True, exist_ok=True)

    if monthly_series.empty:
        fig, ax = plt.subplots()
        ax.text(0.5, 0.5, "Pas de données sur la luminosité.", ha="center", va="center")
        ax.set_axis_off()
        fig.savefig(output_path, dpi=150, bbox_inches="tight")
        plt.close(fig)
        return output_path.resolve()

    export_plot_dataset(monthly_series, output_path)

    months = monthly_series.index
    fig, ax = plt.subplots(figsize=(10, 4))
    ax.bar(months, monthly_series.values, color="goldenrod", alpha=0.8)
    ax.set_ylabel("Heures de luminosité par jour")
    ax.set_xlabel("Mois")
    ax.xaxis.set_major_locator(mdates.AutoDateLocator())
    ax.xaxis.set_major_formatter(mdates.ConciseDateFormatter(ax.xaxis.get_major_locator()))
    ax.set_title(title)
    ax.grid(True, axis="y", linestyle=":", alpha=0.5)
    fig.tight_layout()
    fig.savefig(output_path, dpi=150)
    plt.close(fig)
    return output_path.resolve()
