"""Admin router for brand configuration management."""
import os
import uuid
from typing import Optional

from fastapi import APIRouter, Body, Depends, HTTPException, UploadFile, File
from sqlalchemy.ext.asyncio import AsyncSession
from sqlmodel import select

from models.sql.brand_config import BrandConfigModel
from models.sql.user import UserModel
from services.database import get_async_session
from api.middlewares.rbac_middleware import check_team_admin
from utils.auth_dependencies import require_client_admin

BRAND_CONFIG_ROUTER = APIRouter(tags=["Admin - Brand Config"])

DATA_DIR = os.environ.get("DATA_DIR", "data")


def _ensure_dir(path: str) -> None:
    os.makedirs(path, exist_ok=True)


@BRAND_CONFIG_ROUTER.get("/clients/{client_id}/brand")
async def get_brand_config(
    client_id: uuid.UUID,
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_team_admin(admin, client_id, session)

    result = await session.execute(
        select(BrandConfigModel).where(BrandConfigModel.client_id == client_id)
    )
    config = result.scalar_one_or_none()
    if not config:
        return {
            "id": None,
            "client_id": str(client_id),
            "primary_colors": None,
            "secondary_colors": None,
            "fonts": None,
            "logo_paths": None,
            "voice_rules": None,
            "voice_examples": None,
            "guideline_doc_path": None,
        }

    return {
        "id": str(config.id),
        "client_id": str(config.client_id),
        "primary_colors": config.primary_colors,
        "secondary_colors": config.secondary_colors,
        "fonts": config.fonts,
        "logo_paths": config.logo_paths,
        "voice_rules": config.voice_rules,
        "voice_examples": config.voice_examples,
        "guideline_doc_path": config.guideline_doc_path,
    }


@BRAND_CONFIG_ROUTER.put("/clients/{client_id}/brand")
async def update_brand_config(
    client_id: uuid.UUID,
    primary_colors: Optional[list] = Body(None, embed=True),
    secondary_colors: Optional[list] = Body(None, embed=True),
    fonts: Optional[dict] = Body(None, embed=True),
    voice_rules: Optional[str] = Body(None, embed=True),
    voice_examples: Optional[list] = Body(None, embed=True),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_team_admin(admin, client_id, session)

    result = await session.execute(
        select(BrandConfigModel).where(BrandConfigModel.client_id == client_id)
    )
    config = result.scalar_one_or_none()

    if not config:
        config = BrandConfigModel(client_id=client_id)

    if primary_colors is not None:
        config.primary_colors = primary_colors
    if secondary_colors is not None:
        config.secondary_colors = secondary_colors
    if fonts is not None:
        config.fonts = fonts
    if voice_rules is not None:
        config.voice_rules = voice_rules
    if voice_examples is not None:
        config.voice_examples = voice_examples

    session.add(config)
    await session.commit()

    return {
        "id": str(config.id),
        "client_id": str(config.client_id),
        "primary_colors": config.primary_colors,
        "secondary_colors": config.secondary_colors,
        "fonts": config.fonts,
        "logo_paths": config.logo_paths,
        "voice_rules": config.voice_rules,
        "voice_examples": config.voice_examples,
        "guideline_doc_path": config.guideline_doc_path,
    }


@BRAND_CONFIG_ROUTER.post("/clients/{client_id}/brand/logo")
async def upload_logo(
    client_id: uuid.UUID,
    file: UploadFile = File(...),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_team_admin(admin, client_id, session)

    logo_dir = os.path.join(DATA_DIR, "clients", str(client_id), "logos")
    _ensure_dir(logo_dir)

    filename = f"{uuid.uuid4()}_{file.filename}"
    file_path = os.path.join(logo_dir, filename)

    content = await file.read()
    with open(file_path, "wb") as f:
        f.write(content)

    # Update brand config
    result = await session.execute(
        select(BrandConfigModel).where(BrandConfigModel.client_id == client_id)
    )
    config = result.scalar_one_or_none()
    if not config:
        config = BrandConfigModel(client_id=client_id, logo_paths=[file_path])
    else:
        paths = config.logo_paths or []
        paths.append(file_path)
        config.logo_paths = paths

    session.add(config)
    await session.commit()

    return {"message": "Logo uploaded", "path": file_path}


@BRAND_CONFIG_ROUTER.delete("/clients/{client_id}/brand/logo/{index}")
async def delete_logo(
    client_id: uuid.UUID,
    index: int,
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_team_admin(admin, client_id, session)

    result = await session.execute(
        select(BrandConfigModel).where(BrandConfigModel.client_id == client_id)
    )
    config = result.scalar_one_or_none()
    if not config or not config.logo_paths:
        raise HTTPException(status_code=404, detail="No logos found")

    if index < 0 or index >= len(config.logo_paths):
        raise HTTPException(status_code=400, detail="Invalid logo index")

    removed_path = config.logo_paths.pop(index)
    # Try to delete the file
    if os.path.exists(removed_path):
        os.remove(removed_path)

    session.add(config)
    await session.commit()

    return {"message": "Logo removed"}


@BRAND_CONFIG_ROUTER.post("/clients/{client_id}/brand/guideline")
async def upload_guideline(
    client_id: uuid.UUID,
    file: UploadFile = File(...),
    admin: UserModel = Depends(require_client_admin),
    session: AsyncSession = Depends(get_async_session),
):
    await check_team_admin(admin, client_id, session)

    guideline_dir = os.path.join(DATA_DIR, "clients", str(client_id), "guidelines")
    _ensure_dir(guideline_dir)

    filename = f"{uuid.uuid4()}_{file.filename}"
    file_path = os.path.join(guideline_dir, filename)

    content = await file.read()
    with open(file_path, "wb") as f:
        f.write(content)

    result = await session.execute(
        select(BrandConfigModel).where(BrandConfigModel.client_id == client_id)
    )
    config = result.scalar_one_or_none()
    if not config:
        config = BrandConfigModel(client_id=client_id, guideline_doc_path=file_path)
    else:
        config.guideline_doc_path = file_path

    session.add(config)
    await session.commit()

    return {"message": "Guideline uploaded", "path": file_path}
