"""FastAPI application — cPanel / MySQL edition."""
import logging
import os
import uuid
from datetime import datetime, timezone
from pathlib import Path
from typing import List

from dotenv import load_dotenv
from fastapi import APIRouter, Depends, FastAPI
from pydantic import BaseModel, Field
from sqlalchemy import select
from sqlalchemy.orm import Session
from starlette.middleware.cors import CORSMiddleware

ROOT_DIR = Path(__file__).parent
load_dotenv(ROOT_DIR / ".env")

from core.auth import hash_password, verify_password  # noqa: E402
from db.models import StatusCheck as StatusCheckModel, User  # noqa: E402
from db.session import get_session, init_db  # noqa: E402
from routes.auth import router as auth_router  # noqa: E402
from routes.admin_users import router as admin_router  # noqa: E402
from routes.device import router as device_router  # noqa: E402
from routes.iptv_proxy import router as iptv_proxy_router  # noqa: E402
from routes.public import auth_router as shared_profiles_router  # noqa: E402
from routes.public import router as public_router  # noqa: E402
from routes.subscription import router as subscription_router  # noqa: E402

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
)
logger = logging.getLogger(__name__)

app = FastAPI(title="NADIPLAY API (cPanel)")
api_router = APIRouter(prefix="/api")


class StatusCheck(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    client_name: str
    timestamp: str = Field(default_factory=lambda: datetime.now(timezone.utc).isoformat())


class StatusCheckCreate(BaseModel):
    client_name: str


@api_router.get("/")
def root():
    return {"message": "Hello World"}


@api_router.post("/status", response_model=StatusCheck)
def create_status_check(body: StatusCheckCreate, db: Session = Depends(get_session)):
    obj = StatusCheck(client_name=body.client_name)
    db.add(StatusCheckModel(id=obj.id, client_name=obj.client_name, timestamp=obj.timestamp))
    db.commit()
    return obj


@api_router.get("/status", response_model=List[StatusCheck])
def get_status_checks(db: Session = Depends(get_session)):
    rows = db.scalars(select(StatusCheckModel).limit(1000)).all()
    return [StatusCheck(id=r.id, client_name=r.client_name, timestamp=r.timestamp) for r in rows]


app.include_router(api_router)
app.include_router(auth_router)
app.include_router(admin_router)
app.include_router(subscription_router)
app.include_router(public_router)
app.include_router(shared_profiles_router)
app.include_router(device_router)
app.include_router(iptv_proxy_router)

app.add_middleware(
    CORSMiddleware,
    allow_credentials=True,
    allow_origins=os.environ.get("CORS_ORIGINS", "*").split(","),
    allow_methods=["*"],
    allow_headers=["*"],
)


def seed_admin():
    """Idempotent admin seed. Re-syncs password from env on every startup."""
    admin_username = os.environ.get("ADMIN_USERNAME", "admin").strip().lower()
    admin_password = os.environ.get("ADMIN_PASSWORD", "admin123")

    from db.session import session_scope
    with session_scope() as db:
        existing = db.scalar(select(User).where(User.username == admin_username))
        if existing is None:
            db.add(User(
                id=str(uuid.uuid4()),
                username=admin_username,
                password_hash=hash_password(admin_password),
                role="admin",
                created_at=datetime.now(timezone.utc).isoformat(),
                expiry_at=None,
            ))
            logger.info("Seeded admin user '%s'", admin_username)
        elif not verify_password(admin_password, existing.password_hash):
            existing.password_hash = hash_password(admin_password)
            existing.role = "admin"
            logger.info("Updated admin password for '%s'", admin_username)


# Run migrations + seed at import time (Passenger imports once per worker).
init_db()
seed_admin()
