import datetime

from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.ext.asyncio import AsyncSession

from src.services.org_unit_service import OrgUnitService
from src.db.models.app_user import AppUser
from src.domain.schemas import (
    BaseListResponse,
    BaseSingleResponse,
    FormPhaseCreate,
    FormPhaseResponse,
    FormPhaseUpdate,
)
from src.services.budget_form_service import BudgetFormService
from src.services.form_phase_service import FormPhaseService
from src.api.v1.deps import (
    get_current_active_user_with_set_db,
    require_admin,
)
from src.db.session import get_db

router = APIRouter(prefix="/stages", tags=["stages"])


def timezone_from_offset(offset: str) -> datetime.timezone | None:
    if not offset:
        return None
    
    hours = int(offset[1:])
    return datetime.timezone(
        datetime.timedelta(
            hours=hours if offset[0] == '+' else -hours
        )
    )


@router.get("/form/{form_id}")
async def get_form_phases(
    form_id: int,
    sheet: str | None = None,
    phase_code: str | None = None,
    db: AsyncSession = Depends(get_db),
    current_user: AppUser = Depends(get_current_active_user_with_set_db),
) -> BaseListResponse[FormPhaseResponse]:
    fp_service = FormPhaseService(db)
    org_unit_service = OrgUnitService(db)
    bf_service = BudgetFormService(db)

    phases = await fp_service.get_list(
        budget_form_id=form_id,
        user=current_user,
        sheet=sheet,
        phase_code=phase_code,
    )
    if phases:
        form = await bf_service.get(user=current_user, budget_form_id=form_id)
        org_unit = await org_unit_service.get(user=current_user, org_unit_id=form.org_unit_id)
        result = [FormPhaseResponse.model_validate(p) for p in phases]
        if org_unit.utc_offset:
            tz = timezone_from_offset(org_unit.utc_offset)
            for element in result:
                if element.opens_at:
                    element.opens_at = element.opens_at.astimezone(tz)
                if element.closes_at:
                    element.closes_at = element.closes_at.astimezone(tz)
    else:
        result = []
    for element in result:
        pass
    return BaseListResponse(
        result=result,
        count=len(phases),
    )


@router.post("/form/{form_id}")
async def create_form_phase(
        form_id: int,
        body: FormPhaseCreate,
        db: AsyncSession = Depends(get_db),
        current_user: AppUser = Depends(require_admin),
) -> BaseSingleResponse[FormPhaseResponse]:
    bf_service = BudgetFormService(db)
    form = await bf_service.get(budget_form_id=form_id, user=current_user, load_form_type=True)
    if not form:
        raise HTTPException(404, "Форма не найдена")
    
    org_unit_service = OrgUnitService(db)
    org_unit = await org_unit_service.get(user=current_user, org_unit_id=form.org_unit_id)

    fp_service = FormPhaseService(db)
    phase = await fp_service.create(
        budget_form=form, 
        body=body, 
        user=current_user,
    )

    result = FormPhaseResponse.model_validate(phase)

    if org_unit.utc_offset:
        tz = timezone_from_offset(org_unit.utc_offset)
        if result.opens_at:
            result.opens_at = result.opens_at.astimezone(tz)
        if result.closes_at:
            result.closes_at = result.closes_at.astimezone(tz)
    return BaseSingleResponse(result=result)


@router.patch("/form/{form_id}/{sheet}/{phase_code}")
async def update_form_phase(
    form_id: int,
    sheet: str,
    phase_code: str,
    body: FormPhaseUpdate,
    db: AsyncSession = Depends(get_db),
    current_user: AppUser = Depends(require_admin),
) -> BaseSingleResponse[FormPhaseResponse]:
    bf_service = BudgetFormService(db)
    form = await bf_service.get(budget_form_id=form_id, user=current_user, load_form_type=True)
    if not form:
        raise HTTPException(404, "Форма не найдена")
    
    fp_service = FormPhaseService(db)
    phase = await fp_service.update(
        budget_form=form,
        sheet=sheet,
        phase_code=phase_code,
        body=body,
        user=current_user,
    )
    
    if not phase:
        raise HTTPException(404, "Этап не найден")

    org_unit_service = OrgUnitService(db)
    org_unit = await org_unit_service.get(user=current_user, org_unit_id=form.org_unit_id)
    result = FormPhaseResponse.model_validate(phase)

    if org_unit.utc_offset:
        tz = timezone_from_offset(org_unit.utc_offset)
        if result.opens_at:
            result.opens_at = result.opens_at.astimezone(tz)
        if result.closes_at:
            result.closes_at = result.closes_at.astimezone(tz)
    return BaseSingleResponse(result=result)


@router.delete("/form/{form_id}/{sheet}/{phase_code}")
async def delete_form_phase(
    form_id: int,
    sheet: str,
    phase_code: str,
    db: AsyncSession = Depends(get_db),
    current_user: AppUser = Depends(require_admin),
):
    bf_service = BudgetFormService(db)
    form = await bf_service.get(budget_form_id=form_id, user=current_user)
    if not form:
        raise HTTPException(404, "Форма не найдена")
    
    fp_service = FormPhaseService(db)
    deleted = await fp_service.delete(
        budget_form_id=form_id,
        sheet=sheet,
        phase_code=phase_code,
        user=current_user,
    )
    if not deleted:
        raise HTTPException(404, "Этап не найден")
