import asyncio
import logging

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

from app.api.router import api_router
from app.core.config import get_settings
from app.services.fiscal_document_inbox_service import sync_all_ready_fiscal_document_inboxes
from app.services.tenant_store import get_tenant_store


settings = get_settings()
settings.validate_runtime()
app = FastAPI(title=settings.app_name, version="0.1.0")
_fiscal_inbox_task: asyncio.Task[None] | None = None
_timeclock_auto_close_task: asyncio.Task[None] | None = None
logger = logging.getLogger(__name__)

app.add_middleware(
    CORSMiddleware,
    allow_origins=settings.cors_origins_list,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.include_router(api_router)


def _fiscal_inbox_poll_interval_seconds() -> int:
    return max(300, settings.fiscal_document_inbox_poll_seconds)


def _fiscal_inbox_startup_delay_seconds() -> int:
    return min(30, _fiscal_inbox_poll_interval_seconds())


async def _fiscal_inbox_poll_loop() -> None:
    await asyncio.sleep(_fiscal_inbox_startup_delay_seconds())
    while True:
        try:
            await sync_all_ready_fiscal_document_inboxes()
        except Exception:
            logger.exception("Fiscal document inbox polling failed")
        await asyncio.sleep(_fiscal_inbox_poll_interval_seconds())


async def _timeclock_auto_close_poll_loop() -> None:
    await asyncio.sleep(2)
    while True:
        try:
            result = await asyncio.to_thread(get_tenant_store().auto_close_stale_timeclock_entries)
            closed_count = int(result.get("closed_count") or 0)
            if closed_count:
                logger.info("Automatically closed %s stale timeclock shift(s) at 06:00 Europe/Rome", closed_count)
            for error in result.get("errors") or []:
                logger.error("Timeclock auto-close failed for tenant: %s", error)
        except Exception:
            logger.exception("Timeclock auto-close polling failed")
        await asyncio.sleep(60)


@app.on_event("startup")
async def startup_background_tasks() -> None:
    global _fiscal_inbox_task, _timeclock_auto_close_task
    if _fiscal_inbox_task is None or _fiscal_inbox_task.done():
        _fiscal_inbox_task = asyncio.create_task(_fiscal_inbox_poll_loop())
    if _timeclock_auto_close_task is None or _timeclock_auto_close_task.done():
        _timeclock_auto_close_task = asyncio.create_task(_timeclock_auto_close_poll_loop())


@app.on_event("shutdown")
async def shutdown_background_tasks() -> None:
    global _fiscal_inbox_task, _timeclock_auto_close_task
    if _fiscal_inbox_task is not None:
        _fiscal_inbox_task.cancel()
        try:
            await _fiscal_inbox_task
        except asyncio.CancelledError:
            pass
        _fiscal_inbox_task = None
    if _timeclock_auto_close_task is not None:
        _timeclock_auto_close_task.cancel()
        try:
            await _timeclock_auto_close_task
        except asyncio.CancelledError:
            pass
        _timeclock_auto_close_task = None
