from fastapi import APIRouter, Request, Form, Depends, HTTPException
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select, or_
from app.core.database import get_db
from app.models.models import Customer, CustomerStatus, AuditLog
from app.core.security import require_roles, get_current_user
import os

router = APIRouter(dependencies=[Depends(require_roles("teknisi"))])
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
templates = Jinja2Templates(directory=os.path.join(BASE_DIR, "app/templates"))

@router.get("/tasks", response_class=HTMLResponse)
async def task_list(request: Request, db: AsyncSession = Depends(get_db), user=Depends(get_current_user)):
    try:
        # New requests are an open technician queue. Once a technician starts
        # a request, it remains visible only to the assigned technician.
        result = await db.execute(
            select(Customer)
            .where(
                Customer.is_archived == False,
                or_(
                    Customer.assigned_teknisi_id == user.id,
                    (Customer.status == CustomerStatus.REQUEST.value)
                    & (Customer.assigned_teknisi_id.is_(None)),
                ),
            )
            .order_by(Customer.created_at.desc(), Customer.id.desc())
        )
        tasks = result.scalars().all()
        return templates.TemplateResponse(
            request=request,
            name="tasks.html",
            context={"request": request, "tasks": tasks}
        )
    except Exception as e:
        with open("debug_error.log", "w") as f:
            import traceback
            traceback.print_exc(file=f)
        raise e

@router.post("/update-task/{customer_id}")
async def update_task(
    customer_id: int,
    status: str = Form(...),
    db: AsyncSession = Depends(get_db),
    user=Depends(get_current_user),
):
    result = await db.execute(
        select(Customer).where(
            Customer.id == customer_id,
            Customer.is_archived == False,
            or_(
                Customer.assigned_teknisi_id == user.id,
                (Customer.status == CustomerStatus.REQUEST.value)
                & (Customer.assigned_teknisi_id.is_(None)),
            ),
        )
    )
    customer = result.scalar_one_or_none()
    if customer:
        next_status = {
            "request": "installing",
            "installing": "configuring",
            "configuring": "pending_provisioning",
            "pending_provisioning": "active",
        }.get(customer.status)
        if status != next_status:
            raise HTTPException(status_code=422, detail="Teknisi hanya dapat meneruskan status ke tahap berikutnya")
        # Technician status flow is independent from hardware provisioning.
        # Provisioning has its own state and may be completed by operations later.
        if customer.assigned_teknisi_id is None:
            customer.assigned_teknisi_id = user.id
        customer.status = status
        db.add(AuditLog(
            user_id=user.id,
            action="technician_status_update",
            entity="customer",
            entity_id=customer.id,
            detail=f"status -> {status}",
        ))
        await db.commit()
    return RedirectResponse(url="/tasks", status_code=303)
