import sys
import os
from datetime import datetime, timedelta
import calendar

# Přidání adresáře src do sys.path, aby bylo možné importovat moduly
sys.path.insert(0, os.path.join(os.path.dirname(__file__)))

import database
import data_fetcher
import holidays

# Global debug flag
DEBUG = False

def debug_print(*args, **kwargs):
    """Print debug messages only if debug mode is enabled."""
    if DEBUG:
        print(*args, **kwargs)

def set_debug_mode(debug):
    """Set the debug mode for this module."""
    global DEBUG
    DEBUG = debug

def get_last_day_of_month(year, month):
    """
    Vrátí datum posledního dne v daném měsíci ve formátu DD.MM.YYYY.
    
    :param year: Rok
    :param month: Měsíc (1-12)
    :return: Datum posledního dne měsíce ve formátu DD.MM.YYYY
    """
    # Poslední den měsíce
    last_day = calendar.monthrange(year, month)[1]
    return f"{last_day:02d}.{month:02d}.{year}"

def get_valid_last_day_of_month(year, month):
    """
    Vrátí platné datum posledního pracovního dne v daném měsíci.
    Pokud je poslední den víkend nebo svátek, vrátí předchozí pracovní den.
    
    :param year: Rok
    :param month: Měsíc (1-12)
    :return: Datum posledního pracovního dne měsíce ve formátu DD.MM.YYYY, nebo None
    """
    # Poslední den měsíce
    last_day = calendar.monthrange(year, month)[1]
    
    # Začneme od posledního dne a jdeme zpět, dokud nenajdeme pracovní den
    for day in range(last_day, 0, -1):
        date_str = f"{day:02d}.{month:02d}.{year}"
        # Zkontrolujeme, zda je to pracovní den (není víkend ani svátek)
        if not holidays.is_weekend(date_str) and not holidays.is_holiday(date_str):
            return date_str
    
    return None

def get_tax_yearly_average(year, currency_code):
    """
    Vypočítá jednotný kurz pro daňové účely podle metodiky GFŘ.
    Jedná se o aritmetický průměr kurzů k poslednímu dni každého měsíce v roce.
    
    :param year: Rok
    :param currency_code: Kód měny (např. USD)
    :return: Jednotný kurz pro daňové účely nebo None
    """
    monthly_rates = []
    monthly_dates = []
    
    # Pro každý měsíc získáme kurz k poslednímu dni
    for month in range(1, 13):
        # Získáme poslední pracovní den měsíce
        date_str = get_valid_last_day_of_month(year, month)
        if date_str:
            rate = database.get_rate(date_str, currency_code)
            if rate is not None:
                monthly_rates.append(rate)
                monthly_dates.append(date_str)
                debug_print(f"Měsíc {month:02d}: {date_str} = {rate}")
            else:
                debug_print(f"Měsíc {month:02d}: {date_str} = kurz nenalezen")
        else:
            debug_print(f"Měsíc {month:02d}: nelze najít platný den")
    
    debug_print(f"Počet měsíců s kurzy: {len(monthly_rates)}/12")
    
    # Musíme mít kurzy pro všech 12 měsíců
    if len(monthly_rates) != 12:
        debug_print(f"Varování: Nenalezeny kurzy pro všech 12 měsíců ({len(monthly_rates)}/12)")
        return None
    
    # Výpočet aritmetického průměru
    average = sum(monthly_rates) / len(monthly_rates)
    debug_print(f"Součet kurzů: {sum(monthly_rates):.6f}")
    debug_print(f"Počet měsíců: {len(monthly_rates)}")
    debug_print(f"Jednotný kurz pro daňové účely: {average:.6f}")
    
    return average

def get_working_days_in_month(year, month):
    """
    Vrátí seznam pracovních dní v daném měsíci.
    
    :param year: Rok
    :param month: Měsíc (1-12)
    :return: Seznam pracovních dnů ve formátu DD.MM.YYYY
    """
    working_days = []
    
    # Poslední den měsíce
    last_day = calendar.monthrange(year, month)[1]
    
    for day in range(1, last_day + 1):
        date_str = f"{day:02d}.{month:02d}.{year}"
        # Zkontrolujeme, zda je to pracovní den (není víkend ani svátek)
        if not holidays.is_weekend(date_str) and not holidays.is_holiday(date_str):
            working_days.append(date_str)
    
    return working_days

def get_working_days_in_quarter(year, quarter):
    """
    Vrátí seznam pracovních dní ve čtvrtletí.
    
    :param year: Rok
    :param quarter: Čtvrtletí (1-4)
    :return: Seznam pracovních dnů ve formátu DD.MM.YYYY
    """
    working_days = []
    
    # Určíme měsíce v čtvrtletí
    start_month = (quarter - 1) * 3 + 1
    end_month = start_month + 2
    
    for month in range(start_month, end_month + 1):
        working_days.extend(get_working_days_in_month(year, month))
    
    return working_days

def get_working_days_in_year(year):
    """
    Vrátí seznam pracovních dní v roce.
    
    :param year: Rok
    :return: Seznam pracovních dnů ve formátu DD.MM.YYYY
    """
    working_days = []
    
    for month in range(1, 13):
        working_days.extend(get_working_days_in_month(year, month))
    
    return working_days

def calculate_average_rate_for_dates(dates, currency_code):
    """
    Vypočítá průměrný kurz pro zadané datumy.
    
    :param dates: Seznam datumů ve formátu DD.MM.YYYY
    :param currency_code: Kód měny (např. USD)
    :return: Průměrný kurz nebo None pokud nejsou k dispozici žádné kurzy
    """
    if not dates:
        return None
    
    rates = []
    for date in dates:
        rate = database.get_rate(date, currency_code)
        if rate is not None:
            rates.append(rate)
    
    if not rates:
        return None
    
    return sum(rates) / len(rates)

def generate_yearly_stats(year, currency_code, output_dir="data"):
    """
    Vygeneruje statistiky pro zadaný rok a měnu.
    
    :param year: Rok
    :param currency_code: Kód měny (např. USD)
    :param output_dir: Adresář pro ukládání dat
    :return: Slovník se statistikami
    """
    debug_print(f"Generuji statistiky pro {currency_code} za rok {year}...")

    # Zkontrolujeme, zda databáze obsahuje data pro daný rok
    debug_print(f"Stahuji roční data pro rok {year}...")
    os.makedirs("data", exist_ok=True)
    data_fetcher.download_yearly_data(year, output_dir="data", force=False)

    # Vypočítáme jednotný kurz pro daňové účely
    tax_average = get_tax_yearly_average(year, currency_code)

    # Získáme pracovní dny v roce pro ostatní statistiky
    working_days = get_working_days_in_year(year)
    debug_print(f"Počet pracovních dní v roce {year}: {len(working_days)}")

    # Vypočítáme průměrný kurz pro celý rok (všechny pracovní dny)
    yearly_avg = calculate_average_rate_for_dates(working_days, currency_code)

    # Vypočítáme průměrné kurzy pro jednotlivé měsíce
    monthly_stats = {}
    for month in range(1, 13):
        month_working_days = get_working_days_in_month(year, month)
        if month_working_days:
            month_avg = calculate_average_rate_for_dates(month_working_days, currency_code)
            monthly_stats[month] = {
                'average': month_avg,
                'working_days_count': len(month_working_days)
            }

    # Vypočítáme průměrné kurzy pro čtvrtletí
    quarterly_stats = {}
    for quarter in range(1, 5):
        quarter_working_days = get_working_days_in_quarter(year, quarter)
        if quarter_working_days:
            quarter_avg = calculate_average_rate_for_dates(quarter_working_days, currency_code)
            quarterly_stats[quarter] = {
                'average': quarter_avg,
                'working_days_count': len(quarter_working_days)
            }

    return {
        'year': year,
        'currency': currency_code,
        'tax_yearly_average': tax_average,  # Jednotný kurz pro daňové účely
        'yearly_average': yearly_avg,       # Průměr všech pracovních dní
        'monthly_stats': monthly_stats,
        'quarterly_stats': quarterly_stats,
        'total_working_days': len(working_days)
    }

def print_stats(stats):
    """
    Vytiskne statistiky ve formátované podobě.
    
    :param stats: Slovník se statistikami
    """
    year = stats['year']
    currency = stats['currency']

    print(f"\nStatistiky pro {currency} za rok {year}:")
    print("=" * 50)

    if stats['tax_yearly_average']:
        print(f"Jednotný kurz pro daňové účely: {stats['tax_yearly_average']:.3f}")
    else:
        print("Jednotný kurz pro daňové účely: N/A")

    if stats['yearly_average']:
        print(f"Průměr všech pracovních dní: {stats['yearly_average']:.3f}")
    else:
        print("Průměr všech pracovních dní: N/A")

    print(f"Celkový počet pracovních dní: {stats['total_working_days']}")

    print("\nPrůměry podle čtvrtletí:")
    print("-" * 30)
    for quarter in range(1, 5):
        if quarter in stats['quarterly_stats']:
            q_stats = stats['quarterly_stats'][quarter]
            if q_stats['average']:
                print(f"  Q{quarter}: {q_stats['average']:.3f} ({q_stats['working_days_count']} pracovních dní)")
            else:
                print(f"  Q{quarter}: N/A ({q_stats['working_days_count']} pracovních dní)")
        else:
            print(f"  Q{quarter}: N/A")

    print("\nPrůměry podle měsíců:")
    print("-" * 30)
    czech_months = [
        "", "Leden", "Únor", "Březen", "Duben", "Květen", "Červen",
        "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"
    ]

    for month in range(1, 13):
        if month in stats['monthly_stats']:
            m_stats = stats['monthly_stats'][month]
            if m_stats['average']:
                print(f"  {czech_months[month]}: {m_stats['average']:.3f} ({m_stats['working_days_count']} pracovních dní)")
            else:
                print(f"  {czech_months[month]}: N/A ({m_stats['working_days_count']} pracovních dní)")
        else:
            print(f"  {czech_months[month]}: N/A")

# Příklad použití
if __name__ == "__main__":
    # Inicializace databáze (pro případ spuštění samostatně)
    database.init_db()

    # Test
    # stats = generate_yearly_stats(2020, "USD")
    # print_stats(stats)