from __future__ import annotations

from fastapi import APIRouter, Depends, HTTPException, Query, status

from app.core.crypto import create_access_token
from app.core.dependencies import get_current_user, require_superuser
from app.modules.sync import repository as sync_repo
from app.modules.sync.schemas import EnterpriseOut, FarmHubOut
from app.modules.users.models import User

router = APIRouter()


@router.get("/enterprises")
def list_enterprises(user: User = Depends(get_current_user)):
    # Superuser sees all; regular users see memberships only (simplified v1)
    if user.is_superuser:
        from sqlalchemy import select

        from app.core.database import session_scope
        from app.modules.sync.models import Enterprise

        with session_scope() as db:
            rows = list(db.scalars(select(Enterprise).order_by(Enterprise.name)))
            return [
                EnterpriseOut(id=r.id, name=r.name, slug=r.slug, status=r.status).model_dump()
                for r in rows
            ]
    from sqlalchemy import select

    from app.core.database import session_scope
    from app.modules.sync.models import Enterprise, EnterpriseMember

    with session_scope() as db:
        rows = list(
            db.scalars(
                select(Enterprise)
                .join(EnterpriseMember, EnterpriseMember.enterprise_id == Enterprise.id)
                .where(EnterpriseMember.user_id == user.id)
            )
        )
        return [EnterpriseOut(id=r.id, name=r.name, slug=r.slug, status=r.status).model_dump() for r in rows]


@router.post("/enterprises")
def create_enterprise(body: dict, _: User = Depends(require_superuser)):
    ent = sync_repo.create_enterprise(body["name"], body["slug"])
    return EnterpriseOut(id=ent.id, name=ent.name, slug=ent.slug, status=ent.status).model_dump()


@router.get("/enterprises/{enterprise_id}/farms")
def list_farms(enterprise_id: str, user: User = Depends(get_current_user)):
    member = sync_repo.get_member(user.id, enterprise_id)
    if not member and not user.is_superuser:
        from fastapi import HTTPException, status

        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    hubs = sync_repo.list_farm_hubs(enterprise_id)
    return [
        FarmHubOut(
            id=h.id,
            enterprise_id=h.enterprise_id,
            name=h.name,
            hub_site_id=h.hub_site_id,
            url=h.url,
            status=h.status,
            last_seen=h.last_seen,
            wesp_version=h.wesp_version,
        ).model_dump()
        for h in hubs
    ]


@router.post("/enterprises/{enterprise_id}/session")
def enterprise_session(enterprise_id: str, user: User = Depends(get_current_user)):
    member = sync_repo.get_member(user.id, enterprise_id)
    if not member and not user.is_superuser:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    role = member.role if member else "admin"
    farm_ids = None if role == "admin" else sync_repo.list_farm_access(user.id, enterprise_id)
    token = create_access_token(
        user.id,
        user.role,
        user.is_superuser,
        enterprise_id=enterprise_id,
        enterprise_role=role,
        farm_ids=farm_ids,
    )
    return {
        "access_token": token,
        "enterprise_id": enterprise_id,
        "enterprise_role": role,
        "farm_ids": farm_ids,
    }


@router.get("/enterprises/{enterprise_id}/sync-status")
def enterprise_sync_status(enterprise_id: str, user: User = Depends(get_current_user)):
    member = sync_repo.get_member(user.id, enterprise_id)
    if not member and not user.is_superuser:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_FORBIDDEN")
    from app.modules.sync.service import get_sync_metrics

    return get_sync_metrics(enterprise_id)


@router.get("/enterprises/{enterprise_id}/members")
def list_members(enterprise_id: str, user: User = Depends(get_current_user)):
    member = sync_repo.get_member(user.id, enterprise_id)
    if not member or member.role != "admin":
        if not user.is_superuser:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_ADMIN_ONLY")
    from app.modules.users.repository import get_user_by_id

    rows = sync_repo.list_members(enterprise_id)
    return [
        {
            "user_id": m.user_id,
            "role": m.role,
            "email": (get_user_by_id(m.user_id).email if get_user_by_id(m.user_id) else None),
            "farm_ids": sync_repo.list_farm_access(m.user_id, enterprise_id),
        }
        for m in rows
    ]


@router.post("/enterprises/{enterprise_id}/members")
def add_enterprise_member(enterprise_id: str, body: dict, user: User = Depends(get_current_user)):
    member = sync_repo.get_member(user.id, enterprise_id)
    if not member or member.role != "admin":
        if not user.is_superuser:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_ADMIN_ONLY")
    from app.modules.users.repository import get_user_by_email

    target = get_user_by_email(body["email"].strip().lower())
    if not target:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="USER_NOT_FOUND")
    existing = sync_repo.get_member(target.id, enterprise_id)
    if existing:
        sync_repo.set_member_role(target.id, enterprise_id, body.get("role", existing.role))
    else:
        sync_repo.add_member(target.id, enterprise_id, body.get("role", "viewer"))
    for farm_id in body.get("farm_ids") or []:
        sync_repo.grant_farm_access(target.id, farm_id)
    return {"status": "ok", "user_id": target.id}


@router.post("/enterprises/{enterprise_id}/farm-access")
def grant_farm_access(enterprise_id: str, body: dict, user: User = Depends(get_current_user)):
    member = sync_repo.get_member(user.id, enterprise_id)
    if not member or member.role != "admin":
        if not user.is_superuser:
            raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="ENTERPRISE_ADMIN_ONLY")
    sync_repo.grant_farm_access(body["user_id"], body["farm_hub_id"])
    return {"status": "ok"}
