#!/usr/bin/env python3
"""
Skript pro generování souboru data/holidays.json z src/vzor_svatky.json.
"""

import json
import os
from datetime import date, timedelta


def easter_sunday(year):
    """
    Vypočítá datum Velikonoční neděle pro daný rok podle Gaussova algoritmu.
    
    :param year: Rok
    :return: Datum Velikonoční neděle
    """
    # Gausův algoritmus pro výpočet Velikonoc
    a = year % 19
    b = year // 100
    c = year % 100
    d = b // 4
    e = b % 4
    f = (b + 8) // 25
    g = (b - f + 1) // 3
    h = (19 * a + b - d - g + 15) % 30
    i = c // 4
    k = c % 4
    l = (32 + 2 * e + 2 * i - h - k) % 7
    m = (a + 11 * h + 22 * l) // 451
    month = (h + l - 7 * m + 114) // 31
    day = ((h + l - 7 * m + 114) % 31) + 1
    return date(year, month, day)


def load_vzor_svatky():
    """Načte vzorový soubor se svátky."""
    vzor_path = os.path.join(os.path.dirname(__file__), 'vzor_svatky.json')
    with open(vzor_path, 'r', encoding='utf-8') as f:
        return json.load(f)


def generate_holidays_for_year(year, vzor_data):
    """
    Vygeneruje seznam svátků pro daný rok.
    
    :param year: Rok
    :param vzor_data: Data z vzor_svatky.json
    :return: Seznam svátků ve formátu DD.MM
    """
    holidays = set()
    
    # Přidáme ověřené svátky, pokud jsou pro daný rok k dispozici
    if str(year) in vzor_data['overeneSvatky']:
        for svatek in vzor_data['overeneSvatky'][str(year)]:
            # Převedeme datum z YYYY-MM-DD na DD.MM
            datum = svatek['datum']
            den_mesic = datum[8:10] + '.' + datum[5:7]
            holidays.add(den_mesic)
    else:
        # Pro roky bez ověřených svátků použijeme pravidla
        
        # Pevné svátky
        for svatek in vzor_data['pravidlaProBudouciSvatky']['pevneSvatky']:
            # datum je ve formátu MM-DD
            mesic_den = svatek['datum']
            den_mesic = mesic_den[3:5] + '.' + mesic_den[0:2]
            holidays.add(den_mesic)
        
        # Pohyblivé svátky - Velikonoce
        try:
            velikonoce = easter_sunday(year)
            # Velký pátek - 2 dny před Velikonocemi
            velky_patek = velikonoce - timedelta(days=2)
            den_mesic_vp = velky_patek.strftime('%d.%m')
            holidays.add(den_mesic_vp)
            
            # Velikonoční pondělí - 1 den po Velikonocích
            velikonoce_po = velikonoce + timedelta(days=1)
            den_mesic_vpo = velikonoce_po.strftime('%d.%m')
            holidays.add(den_mesic_vpo)
        except Exception as e:
            print(f"Chyba při výpočtu Velikonoc pro rok {year}: {e}")
    
    return sorted(list(holidays))


def generate_all_holidays(vzor_data, start_year=2020, end_year=2030):
    """
    Vygeneruje svátky pro rozsah let.
    
    :param vzor_data: Data z vzor_svatky.json
    :param start_year: Počáteční rok
    :param end_year: Koncový rok
    :return: Slovník ve formátu vhodném pro holidays.json
    """
    holidays_dict = {}
    
    for year in range(start_year, end_year + 1):
        holidays_list = generate_holidays_for_year(year, vzor_data)
        holidays_dict[str(year)] = holidays_list
        print(f"Rok {year}: {len(holidays_list)} svátků")
    
    return holidays_dict


def save_holidays(holidays_dict, output_path):
    """
    Uloží svátky do souboru.
    
    :param holidays_dict: Slovník svátků
    :param output_path: Cesta k výstupnímu souboru
    """
    with open(output_path, 'w', encoding='utf-8') as f:
        json.dump(holidays_dict, f, indent=2, ensure_ascii=False)
    print(f"Svátky byly uloženy do: {output_path}")


def main():
    """Hlavní funkce."""
    print("Generuji soubor se svátky...")
    
    # Načteme vzorová data
    vzor_data = load_vzor_svatky()
    
    # Vygenerujeme svátky pro roky 2020-2030
    holidays_dict = generate_all_holidays(vzor_data, 2020, 2030)
    
    # Uložíme do data/holidays.json
    output_path = os.path.join(os.path.dirname(__file__), '..', 'data', 'holidays.json')
    save_holidays(holidays_dict, output_path)
    
    print("Hotovo!")


if __name__ == '__main__':
    main()