import os
from datetime import datetime, time, timedelta, timezone
from pathlib import Path
from threading import Event, Thread

from dotenv import load_dotenv
from sqlalchemy.orm import Session

from app import crud
from app.database import SessionLocal
from app.logging_utils import get_logger
from app.models import User
from app.services import google_calendar_service

load_dotenv(Path(__file__).resolve().parent.parent / ".env")
load_dotenv()

logger = get_logger(__name__)

REFRESH_INTERVAL_SECONDS = int(os.getenv("RECURRING_DASHBOARD_REFRESH_SECONDS", "60"))
IST_TIMEZONE = timezone(timedelta(hours=5, minutes=30))
CALENDAR_RESYNC_TIME_IST = os.getenv("RECURRING_CALENDAR_RESYNC_TIME_IST", "00:00").strip()

_stop_event = Event()
_worker_thread: Thread | None = None


def start_background_refresh_worker() -> None:
    global _worker_thread

    if _worker_thread and _worker_thread.is_alive():
        return

    refresh_all_users_recurring_visibility()
    _stop_event.clear()
    _worker_thread = Thread(
        target=_run_refresh_loop,
        name="recurring-dashboard-refresh",
        daemon=True,
    )
    _worker_thread.start()
    logger.info(
        "Recurring dashboard refresh worker started. Visibility interval: %s seconds. Calendar resync time (IST): %s.",
        REFRESH_INTERVAL_SECONDS,
        CALENDAR_RESYNC_TIME_IST,
    )


def stop_background_refresh_worker() -> None:
    _stop_event.set()


def refresh_all_users_recurring_visibility() -> None:
    db: Session = SessionLocal()
    try:
        users = (
            db.query(User)
            .filter(User.calendar_sync_enabled.is_(True))
            .filter((User.role == "admin") | (User.approval_status == "approved"))
            .all()
        )
        now_utc = datetime.now(timezone.utc)
        window_end = now_utc + timedelta(days=google_calendar_service.RECURRING_MEETING_WINDOW_DAYS)

        refreshed_users = 0
        for user in users:
            crud.refresh_recurring_candidate_visibility(
                db=db,
                user_id=user.id,
                window_start=now_utc,
                window_end=window_end,
            )
            refreshed_users += 1

        logger.info(
            "Recurring dashboard visibility refresh finished for %s users.",
            refreshed_users,
        )
    finally:
        db.close()


def resync_all_users_recurring_calendar_window() -> None:
    db: Session = SessionLocal()
    try:
        users = (
            db.query(User)
            .filter(User.calendar_sync_enabled.is_(True))
            .filter((User.role == "admin") | (User.approval_status == "approved"))
            .filter(User.access_token.isnot(None))
            .all()
        )

        resynced_users = 0
        days_ahead = max(
            google_calendar_service.DEFAULT_SYNC_DAYS,
            google_calendar_service.RECURRING_MEETING_WINDOW_DAYS,
        )
        for user in users:
            user_id = user.id
            try:
                google_calendar_service.sync_google_calendar(
                    db=db,
                    user=user,
                    days_ahead=days_ahead,
                    auto_schedule_bot=True,
                    full_sync=True,
                    delete_past_events=False,
                )
                resynced_users += 1
            except Exception as exc:
                db.rollback()
                logger.exception(
                    "Recurring calendar window resync failed for user %s. Error: %s.",
                    user_id,
                    exc,
                )

        logger.info(
            "Recurring calendar window resync finished for %s users.",
            resynced_users,
        )
    finally:
        db.close()


def _run_refresh_loop() -> None:
    last_calendar_resync_date = None
    scheduled_resync_time = _parse_daily_resync_time(CALENDAR_RESYNC_TIME_IST)

    while not _stop_event.wait(REFRESH_INTERVAL_SECONDS):
        try:
            refresh_all_users_recurring_visibility()
        except Exception as exc:
            logger.exception("Recurring dashboard visibility refresh failed. Error: %s.", exc)

        now_utc = datetime.now(timezone.utc)
        now_ist = now_utc.astimezone(IST_TIMEZONE)
        scheduled_run_at_ist = datetime.combine(now_ist.date(), scheduled_resync_time, tzinfo=IST_TIMEZONE)
        should_resync_calendar = now_ist >= scheduled_run_at_ist and last_calendar_resync_date != now_ist.date()
        if not should_resync_calendar:
            continue

        try:
            resync_all_users_recurring_calendar_window()
            last_calendar_resync_date = now_ist.date()
        except Exception as exc:
            logger.exception("Recurring calendar window resync failed. Error: %s.", exc)


def _parse_daily_resync_time(value: str) -> time:
    try:
        hours_text, minutes_text = value.split(":", 1)
        hours = int(hours_text)
        minutes = int(minutes_text)
        if hours < 0 or hours > 23 or minutes < 0 or minutes > 59:
            raise ValueError
        return time(hour=hours, minute=minutes)
    except ValueError as exc:
        raise RuntimeError(
            "Invalid RECURRING_CALENDAR_RESYNC_TIME_IST value. Use HH:MM in 24-hour format, for example 06:00."
        ) from exc
