import os
import asyncio
from dotenv import load_dotenv
from aiogram import Bot, Dispatcher, F
from aiogram.types import Message, InlineKeyboardButton, CallbackQuery
from aiogram.filters import CommandStart, Command
from aiogram.utils.keyboard import InlineKeyboardBuilder
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger

from parser import (
    get_river_data, 
    get_weather_popelnyky, 
    get_fishing_forecast, 
    format_river_msg, 
    format_fishing_msg, 
    format_weather_msg
)

load_dotenv()
BOT_TOKEN = os.getenv("BOT_TOKEN")
CHANNEL_ID = os.getenv("CHANNEL_ID")

bot = Bot(token=BOT_TOKEN)
dp = Dispatcher()
scheduler = AsyncIOScheduler(timezone="Europe/Kyiv")

# Глобальна змінна для збереження ID останнього надісланого повідомлення про річку
LAST_RIVER_MESSAGE_ID = None

def get_river_keyboard():
    builder = InlineKeyboardBuilder()
    builder.row(
        InlineKeyboardButton(text="🔄 Оновити", callback_data="refresh_river"),
        InlineKeyboardButton(text="📊 10 днів", callback_data="refresh_river_10d")
    )
    return builder.as_markup()

def get_close_keyboard():
    builder = InlineKeyboardBuilder()
    builder.row(InlineKeyboardButton(text="🚫 Закрити", callback_data="close_message"))
    return builder.as_markup()

def get_fishing_keyboard():
    builder = InlineKeyboardBuilder()
    builder.row(InlineKeyboardButton(text="🎣 Період кльову: 👇", callback_data="none"))
    builder.row(
        InlineKeyboardButton(text="🌅 Ранок", callback_data="click_morning"),
        InlineKeyboardButton(text="☀️ Обід", callback_data="click_day"),
        InlineKeyboardButton(text="🌌 Вечір", callback_data="click_evening")
    )
    return builder.as_markup()

def get_weather_keyboard():
    builder = InlineKeyboardBuilder()
    builder.row(InlineKeyboardButton(text="🌤️ Погода на період: 👇", callback_data="none"))
    builder.row(
        InlineKeyboardButton(text="🌅 Ранок", callback_data="wclick_morning"),
        InlineKeyboardButton(text="☀️ Обід", callback_data="wclick_day"),
        InlineKeyboardButton(text="🌌 Вечір", callback_data="wclick_evening")
    )
    return builder.as_markup()

async def send_river_update(forced=False):
    global LAST_RIVER_MESSAGE_ID
    river = get_river_data()
    
    # Якщо рівень "Невідомо" (і це не примусовий виклик), то виходимо
    if river['level'] == "Невідомо" and not forced: 
        return "Помилка АПІ"
    
    msg = await bot.send_message(
        chat_id=CHANNEL_ID, 
        text=format_river_msg(river), 
        parse_mode="HTML", 
        reply_markup=get_river_keyboard()
    )
    LAST_RIVER_MESSAGE_ID = msg.message_id
    return "Рівень надіслано"

async def update_existing_river_post():
    """Фонова задача: автоматично оновлює існуючий пост у каналі новими даними без кліку на кнопку"""
    global LAST_RIVER_MESSAGE_ID
    if LAST_RIVER_MESSAGE_ID is None:
        return
        
    river = get_river_data()
    if river['level'] == "Невідомо": return
    
    try:
        await bot.edit_message_text(
            chat_id=CHANNEL_ID,
            message_id=LAST_RIVER_MESSAGE_ID,
            text=format_river_msg(river),
            parse_mode="HTML",
            reply_markup=get_river_keyboard()
        )
        print(f"[Крон-Оновлення] Успішно актуалізовано дані для поста ID: {LAST_RIVER_MESSAGE_ID}")
    except Exception as e:
        # Очікувана поведінка, якщо дані не змінилися з моменту останньої перевірки
        pass

async def send_daily_combined_report():
    await send_river_update(forced=True)
    await asyncio.sleep(2) 
    await send_daily_forecast()

async def send_daily_forecast():
    river = get_river_data() # Отримуємо дані про річку
    fish = get_fishing_forecast(target_time="morning", river_dict=river) # Передаємо їх сюди
    # ...
  
    weather = get_weather_popelnyky(target_time="morning", is_tomorrow=False)
    weather_tomorrow = get_weather_popelnyky(target_time="day", is_tomorrow=True)
    
    await bot.send_message(
        chat_id=CHANNEL_ID,
        text=format_fishing_msg(fish, river), # Передаємо river тут
        parse_mode="HTML",
        reply_markup=get_fishing_keyboard()
    )
    
    await asyncio.sleep(1)
    
    await bot.send_message(
        chat_id=CHANNEL_ID,
        text=format_weather_msg(weather, weather_tomorrow, "🌅 РАНОК"),
        parse_mode="HTML",
        reply_markup=get_weather_keyboard()
    )
    return "Звіти надіслано"

# --- CALLBACKS ДЛЯ РІЧКИ ---

@dp.callback_query(F.data == "refresh_river")
async def cb_refresh_river(callback: CallbackQuery):
    river = get_river_data()
    try:
        await callback.message.edit_text(text=format_river_msg(river), parse_mode="HTML", reply_markup=get_river_keyboard())
        await callback.answer(f"📸 Оновлено! Рівень: {river['level']}")
    except Exception: await callback.answer("Дані актуальні")

@dp.callback_query(F.data == "refresh_river_10d")
async def cb_refresh_river_10d(callback: CallbackQuery):
    river = get_river_data()
    
    msg_text = (
        "━━━━━━━━━━━━━━━━\n"
        "📊 <b>ІСТОРІЯ РІВНЯ ВОДИ ЗА 10 ДНІВ</b>\n"
        "━━━━━━━━━━━━━━━━\n\n"
        f"{river['history_00']}\n\n"
        "━━━━━━━━━━━━━━━━"
    )
    
    await callback.message.answer(
        text=msg_text,
        parse_mode="HTML",
        reply_markup=get_close_keyboard()
    )
    await callback.answer("Історію завантажено")

@dp.callback_query(F.data == "close_message")
async def cb_close_message(callback: CallbackQuery):
    try:
        await callback.message.delete()
    except Exception:
        await callback.answer("Неможливо видалити повідомлення")

# --- CALLBACKS ДЛЯ КЛЬОВУ ---

@dp.callback_query(F.data.startswith("click_")) 
async def cb_fish_time(callback: CallbackQuery):
    time_key = callback.data.replace("click_", "")
    river = get_river_data() # Отримуємо актуальні дані для річки
    fish_data = get_fishing_forecast(target_time=time_key, river_dict=river)
    try:
        # Передаємо river у функцію форматування
        await callback.message.edit_text(
            text=format_fishing_msg(fish_data, river), 
            parse_mode="HTML", 
            reply_markup=get_fishing_keyboard()
        )
    except Exception: pass
    await callback.answer(f"Кльов: {fish_data['time_name']}")

# --- CALLBACKS ДЛЯ ПОГОДИ ---

@dp.callback_query(F.data.startswith("wclick_"))
async def cb_weather_time(callback: CallbackQuery):
    time_key = callback.data.replace("wclick_", "")
    # Обов'язково новий виклик функції з новим time_key
    weather = get_weather_popelnyky(target_time=time_key, is_tomorrow=False)
    # Використовуй map для визначення періоду
    time_labels = {"morning": "🌅 РАНОК", "day": "☀️ ОБІД", "evening": "🌌 ВЕЧІР"}
    
    # Виклик з is_tomorrow=False (поточний день)
    weather = get_weather_popelnyky(target_time=time_key, is_tomorrow=False)
    weather_tomorrow = get_weather_popelnyky(target_time="day", is_tomorrow=True)
    
    await callback.message.edit_text(
        text=format_weather_msg(weather, weather_tomorrow, time_labels.get(time_key, "РАНОК")), 
        parse_mode="HTML", 
        reply_markup=get_weather_keyboard()
    )
    await callback.answer(f"Погода: {time_labels.get(time_key, 'РАНОК')}")

@dp.callback_query(F.data == "none")
async def cb_placeholder(callback: CallbackQuery):
    await callback.answer("Оберіть період нижче! 👇")

# --- КОМАНДИ ---

@dp.message(CommandStart())
async def cmd_start(message: Message):
    await message.answer("🤖 Бот моніторингу річки Черемош запущено.")

@dp.message(Command("force"))
async def cmd_force(message: Message):
    await message.answer("⏳ Примусове відправлення звіту в канал...")
    try:
        await send_river_update() 
        await asyncio.sleep(1)
        await send_daily_forecast()
        await message.answer("✅ Всі звіти успішно надіслано в канал!")
    except Exception as e:
        await message.answer(f"❌ Сталася помилка при відправці: {e}")

async def main():
    # Перевірка каналу + анонімність бота (інакше пости з підписом імені бота)
    try:
        chat = await bot.get_chat(CHANNEL_ID)
        me = await bot.get_me()
        member = await bot.get_chat_member(CHANNEL_ID, me.id)
        print(f"[START] chat.type={chat.type!r} title={getattr(chat, 'title', None)!r}")
        if chat.type != "channel":
            print("[START][WARN] CHANNEL_ID не є каналом (broadcast)!")
        is_anon = getattr(member, "is_anonymous", None)
        print(f"[START] bot.is_anonymous={is_anon}")
        if is_anon is False:
            print(
                "[START][WARN] Бот НЕ анонімний адмін → у постах видно ім'я бота.\n"
                "  Виправлення: Канал → Адміністратори → цей бот → увімкни «Анонімність» / Anonymous."
            )
    except Exception as e:
        print(f"[START][WARN] Не вдалося перевірити CHANNEL_ID: {e}")

    # Головна публікація комбінованого звіту о 10:00 ранку
    scheduler.add_job(send_daily_combined_report, CronTrigger(hour="10", minute="0", timezone="Europe/Kyiv"))  
    # Автоматична фонова перевірка оновлень кожні 15 хвилин. 
    scheduler.add_job(update_existing_river_post, "interval", minutes=15, timezone="Europe/Kyiv")
    
    scheduler.start()
    await dp.start_polling(bot)

if __name__ == "__main__":
    try: asyncio.run(main())
    except (KeyboardInterrupt, SystemExit): pass