# app/modules/hosting/routes/api/admin_sites.py
"""
Admin API routes for hosted site management.
"""

import logging
from math import ceil

from fastapi import APIRouter, Depends, Path, Query
from pydantic import BaseModel
from sqlalchemy.orm import Session

from app.api.deps import get_current_admin_api
from app.core.database import get_db
from app.modules.hosting.schemas.hosted_site import (
    AcceptProposalRequest,
    GoLiveRequest,
    HostedSiteCreate,
    HostedSiteDeleteResponse,
    HostedSiteDetailResponse,
    HostedSiteListResponse,
    HostedSiteResponse,
    HostedSiteUpdate,
    SendProposalRequest,
)
from app.modules.hosting.schemas.template import TemplateListResponse, TemplateResponse
from app.modules.hosting.services.hosted_site_service import hosted_site_service
from app.modules.hosting.services.poc_builder_service import poc_builder_service
from app.modules.hosting.services.template_service import template_service
from app.modules.tenancy.schemas.auth import UserContext

router = APIRouter(prefix="/sites")
logger = logging.getLogger(__name__)


@router.get("/templates", response_model=TemplateListResponse)
def list_templates(
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """List available industry templates for POC site generation."""
    templates = template_service.list_templates()
    return TemplateListResponse(
        templates=[TemplateResponse(**t) for t in templates],
    )


class PreviewUrlResponse(BaseModel):
    """Response with signed preview URL."""

    preview_url: str
    expires_in_hours: int = 24


@router.get("/sites/{site_id}/preview-url", response_model=PreviewUrlResponse)
def get_preview_url(
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Generate a signed preview URL for a hosted site."""
    from app.core.preview_token import create_preview_token

    site = hosted_site_service.get_by_id(db, site_id)
    store = site.store
    subdomain = store.subdomain or store.store_code
    token = create_preview_token(store.id, subdomain, site.id)
    return PreviewUrlResponse(
        preview_url=f"/storefront/{subdomain}/?_preview={token}",
    )


class BuildPocRequest(BaseModel):
    """Request to build a POC site from prospect + template."""

    prospect_id: int
    template_id: str
    merchant_id: int | None = None
    site_id: int | None = None  # If set, populate existing site instead of creating new one


class BuildPocResponse(BaseModel):
    """Response from POC builder."""

    hosted_site_id: int
    store_id: int
    pages_created: int
    theme_applied: bool
    template_id: str
    subdomain: str | None = None


@router.post("/poc/build", response_model=BuildPocResponse)
def build_poc(
    data: BuildPocRequest,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Build a POC site from prospect data + industry template."""
    result = poc_builder_service.build_poc(
        db,
        prospect_id=data.prospect_id,
        template_id=data.template_id,
        merchant_id=data.merchant_id,
        site_id=data.site_id,
    )
    db.commit()
    return BuildPocResponse(**result)


def _to_response(site) -> HostedSiteResponse:
    """Convert a hosted site model to response schema."""
    return HostedSiteResponse(
        id=site.id,
        store_id=site.store_id,
        prospect_id=site.prospect_id,
        status=site.status.value if hasattr(site.status, "value") else str(site.status),
        business_name=site.business_name,
        contact_name=site.contact_name,
        contact_email=site.contact_email,
        contact_phone=site.contact_phone,
        proposal_sent_at=site.proposal_sent_at,
        proposal_accepted_at=site.proposal_accepted_at,
        went_live_at=site.went_live_at,
        proposal_notes=site.proposal_notes,
        live_domain=site.live_domain,
        internal_notes=site.internal_notes,
        created_at=site.created_at,
        updated_at=site.updated_at,
    )


@router.get("", response_model=HostedSiteListResponse)
def list_sites(
    page: int = Query(1, ge=1),
    per_page: int = Query(20, ge=1, le=100),
    search: str | None = Query(None),
    status: str | None = Query(None),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """List hosted sites with filters and pagination."""
    sites, total = hosted_site_service.get_all(
        db, page=page, per_page=per_page, search=search, status=status,
    )
    return HostedSiteListResponse(
        items=[_to_response(s) for s in sites],
        total=total,
        page=page,
        per_page=per_page,
        pages=ceil(total / per_page) if per_page else 0,
    )


@router.get("/{site_id}", response_model=HostedSiteDetailResponse)
def get_site(
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Get full hosted site detail with services."""
    site = hosted_site_service.get_by_id(db, site_id)
    return site


@router.post("", response_model=HostedSiteResponse)
def create_site(
    data: HostedSiteCreate,
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Create a new hosted site (auto-creates Store)."""
    site = hosted_site_service.create(db, data.model_dump(exclude_none=True))
    db.commit()
    return _to_response(site)



@router.put("/{site_id}", response_model=HostedSiteResponse)
def update_site(
    data: HostedSiteUpdate,
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Update a hosted site."""
    site = hosted_site_service.update(db, site_id, data.model_dump(exclude_none=True))
    db.commit()
    return _to_response(site)


@router.delete("/{site_id}", response_model=HostedSiteDeleteResponse)
def delete_site(
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Delete a hosted site."""
    hosted_site_service.delete(db, site_id)
    db.commit()
    return HostedSiteDeleteResponse(message="Hosted site deleted")


# ── Lifecycle endpoints ────────────────────────────────────────────────

@router.post("/{site_id}/mark-poc-ready", response_model=HostedSiteResponse)
def mark_poc_ready(
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Mark site as POC ready."""
    site = hosted_site_service.mark_poc_ready(db, site_id)
    db.commit()
    return _to_response(site)


@router.post("/{site_id}/send-proposal", response_model=HostedSiteResponse)
def send_proposal(
    data: SendProposalRequest,
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Send proposal to prospect."""
    site = hosted_site_service.send_proposal(db, site_id, notes=data.notes)
    db.commit()
    return _to_response(site)


@router.post("/{site_id}/accept", response_model=HostedSiteResponse)
def accept_proposal(
    data: AcceptProposalRequest,
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Accept proposal: create/link merchant, create subscription."""
    site = hosted_site_service.accept_proposal(db, site_id, merchant_id=data.merchant_id)
    db.commit()
    return _to_response(site)


@router.post("/{site_id}/go-live", response_model=HostedSiteResponse)
def go_live(
    data: GoLiveRequest,
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Go live with a domain."""
    site = hosted_site_service.go_live(db, site_id, domain=data.domain)
    db.commit()
    return _to_response(site)


@router.post("/{site_id}/suspend", response_model=HostedSiteResponse)
def suspend_site(
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Suspend a site."""
    site = hosted_site_service.suspend(db, site_id)
    db.commit()
    return _to_response(site)


@router.post("/{site_id}/cancel", response_model=HostedSiteResponse)
def cancel_site(
    site_id: int = Path(...),
    db: Session = Depends(get_db),
    current_admin: UserContext = Depends(get_current_admin_api),
):
    """Cancel a site."""
    site = hosted_site_service.cancel(db, site_id)
    db.commit()
    return _to_response(site)
