import pandas as pd
import numpy as np
from scipy.signal import find_peaks

def compute_ratios(log_csv: str):
    df = pd.read_csv(log_csv)

    total_farm = df['farm_duration'].sum()   # seconds providing energy
    total_slew = df['duration_s'].sum()      # seconds slewing

    n_sats = df['satellite_id'].nunique()
    day_seconds = 24 * 3600.0 * n_sats

    power_ratio = total_farm / day_seconds
    slew_ratio  = total_slew / day_seconds

    return total_farm, total_slew, power_ratio, slew_ratio, n_sats

def compute_avg_irradiance(irradiance_csv: str):
    irr_df = pd.read_csv(irradiance_csv, index_col=0)

    nonzero_values = irr_df.values[irr_df.values > 0]
    if nonzero_values.size == 0:
        return 0.0

    return nonzero_values.mean()

def compute_total_excess_power(irradiance_csv: str, capacity_csv: str, timestep_sec: float = 60.0):
    # Load irradiance matrix and farm capacities
    irr_df = pd.read_csv(irradiance_csv, index_col=0)
    cap_df = pd.read_csv(capacity_csv)

    # Build farm name → capacity (W) dictionary
    cap_map = cap_df.set_index("Project Name")["Capacity (MW)"].to_dict()
    cap_map_watts = {k: v * 1e6 for k, v in cap_map.items()}

    # Ensure only matching farms are considered
    common_farms = set(irr_df.columns) & set(cap_map_watts.keys())
    if not common_farms:
        raise ValueError("No overlapping farms between irradiance and capacity data")

    total_excess_power = 0.0
    for farm in common_farms:
        farm_irr = irr_df[farm]
        capacity_watts = cap_map_watts[farm]
        power_series = (farm_irr / 1340.0) * capacity_watts  # ✅ correct
        total_excess_power += power_series.sum()

    total_excess_energy = total_excess_power * timestep_sec  # Watt-seconds = Joules
    return total_excess_energy

def compute_darkness_fraction(shadow_csv: str):
    """
    Computes the average fraction of time satellites spend in darkness.
    Returns total dark time, total time, and darkness ratio.
    """
    df = pd.read_csv(shadow_csv)
    
    total_time = len(df)  # one row per minute per satellite
    in_dark = df['in_shadow'].sum()  # assumes boolean or 0/1

    darkness_ratio = in_dark / total_time if total_time > 0 else 0.0
    avg_dark_minutes_per_sat = df.groupby("satellite_id")["in_shadow"].mean() * 1440

    return in_dark, total_time, darkness_ratio, avg_dark_minutes_per_sat

def compute_farm_power_time_peaks(irradiance_csv: str, capacity_csv: str):
    """
    For each farm, returns:
    - total minutes receiving power
    - the two peak hours (UTC) when power is most often delivered
    - the farm's installed capacity in MW
    """
    irr_df = pd.read_csv(irradiance_csv, index_col=0)
    irr_df.index = pd.to_datetime(irr_df.index)

    cap_df = pd.read_csv(capacity_csv)
    cap_map = cap_df.set_index("Project Name")["Capacity (MW)"].to_dict()

    melted = irr_df.reset_index().melt(id_vars='index', var_name='farm', value_name='irradiance')
    melted = melted.rename(columns={"index": "timestamp"})

    active = melted[melted["irradiance"] > 0.0].copy()
    active["hour"] = active["timestamp"].dt.hour + active["timestamp"].dt.minute / 60.0

    results = []
    for farm, group in active.groupby("farm"):
        hist, bins = np.histogram(group["hour"], bins=24 * 2, range=(0, 24))  # 30-minute bins
        peaks, _ = find_peaks(hist)

        peak_hours = bins[peaks]
        top2 = sorted(zip(hist[peaks], peak_hours), reverse=True)[:2]
        peaks_out = [round(h, 2) for _, h in top2]
        capacity = cap_map.get(farm, float('nan'))

        results.append({
            "farm": farm,
            "minutes_receiving_power": len(group),
            "capacity_mw": capacity,
            "peak_hour_1": peaks_out[0] if len(peaks_out) > 0 else None,
            "peak_hour_2": peaks_out[1] if len(peaks_out) > 1 else None
        })

    return pd.DataFrame(results).sort_values("minutes_receiving_power", ascending=False)




if __name__ == "__main__":
    # Hardcoded paths
    log_path = "generated_data/farm_assignment_durations.csv"
    irr_path = "generated_data/farm_irradiance_matrix.csv"
    capacity_path = "solar_data/solar_sites.csv"

    total_farm, total_slew, power_ratio, slew_ratio, n_sats = compute_ratios(log_path)
    avg_irradiance = compute_avg_irradiance(irr_path)
    total_energy_J = compute_total_excess_power(irr_path, capacity_path)

    total_energy_kWh = total_energy_J / 3.6e6
    revenue_total = total_energy_kWh * 0.06  # 6¢ per kWh

    per_sat_energy_kWh = total_energy_kWh / n_sats
    per_sat_revenue = revenue_total / n_sats

    total_sat_energy = (per_sat_energy_kWh*365.25*20)/(1000*1000)
    total_sat_revenue = per_sat_revenue*365.25*20

    shadow_log_path = "generated_data/satellite_shadow_log.csv"
    in_dark, total_time, darkness_ratio, avg_dark_minutes = compute_darkness_fraction(shadow_log_path)

    print("📊 24-Hour Satellite Performance Summary")
    print("─────────────────────────────────────────────────────────────")
    print(f"Number of satellites:                  {n_sats}")
    print(f"✅ Total time providing energy:        {total_farm:.2f} s")
    print(f"⚡ Power transmission ratio:           {power_ratio:.4f} ({power_ratio*100:.2f} %)")
    print(f"🔄 Total slewing time:                 {total_slew:.2f} s")
    print(f"⏱ Slewing ratio:                       {slew_ratio:.4f} ({slew_ratio*100:.2f} %)")
    print()
    print("🌞 Irradiance Delivery Summary")
    print("────────────────────────────────────────────────────────────")
    print(f"📈 Average irradiance (nonzero only):  {avg_irradiance:.6f} W/m²")
    print()
    print("🔋 Excess Energy Summary")
    print("────────────────────────────────────────────────────────────")
    print(f"⚡ Energy delivered in 24hr:           {total_energy_J:.2e} J")
    print(f"⚡ =                                   {total_energy_kWh:.2f} kWh")
    print(f"💵 =                                  ${revenue_total:.2f}")
    print()
    print("📦 Per-Satellite Performance")
    print("────────────────────────────────────────────────────────────")
    print(f"⚡ Per-satellite energy delivered:      {per_sat_energy_kWh:.2f} kWh")
    print(f"💵 Per-satellite earnings:             ${per_sat_revenue:.2f}")
    print()
    print(f"⚡ Over 20 years:                       {total_sat_energy:.2f} TWh")
    print(f"💵 Per-satellite lifetime earnings:    ${total_sat_revenue:.2f}")
    print()
    print("🌑 Eclipse Analysis Summary")
    print("────────────────────────────────────────────────────────────")
    print(f"🕶 Total shadow minutes across all sats: {in_dark:.0f} min")
    print(f"📅 Total minutes simulated:              {total_time:.0f} min")
    print(f"🌓 Darkness ratio:                       {darkness_ratio:.4f} ({darkness_ratio * 100:.2f} %)")
    print()
    print("📊 Per-Satellite Avg Darkness (min/day)")
    for sid, dark_min in avg_dark_minutes.items():
        print(f"🛰 Satellite {int(sid)}: {dark_min:.2f} min/day")
    print()
    
    # Uncomment this if you want to see the delivery times (this is for one small orbit)
    # print("🕒 Peak Delivery Times (UTC)")
    # print("────────────────────────────────────────────────────────────")
    # peak_df = compute_farm_power_time_peaks(irr_path, capacity_path)
    # for _, row in peak_df.iterrows():
    #     print(f"🌾 {row['farm'][:28]:<28} | {row['minutes_receiving_power']:4.0f} min | "
    #         f"⚡ {row['capacity_mw']:6.1f} MW | "
    #         f"📍 Peaks at {row['peak_hour_1']}h, {row['peak_hour_2']}h UTC")