""" Availability rules endpoints """
from typing import List
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException
from sqlmodel import Session

from app.api.deps import (
    CurrentUser,
    SessionDep,
    get_current_active_superuser,
)
from app import crud
from app.models import (
    AvailabilityRuleCreate,
    AvailabilityRuleUpdate,
    AvailabilityRuleOut,
    Service
)

router = APIRouter()

@router.post("/services/{service_id}/availability", response_model=AvailabilityRuleOut)
def create_availability_rule(
    *,
    service_id: UUID,
    obj_in: AvailabilityRuleCreate,
    session: SessionDep,
    current_user: CurrentUser
) -> AvailabilityRuleOut:
    """
    Create a new availability rule for a service.
    """
    # Verify that the service belongs to the current user
    service = session.get(Service, service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    if service.account_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    return crud.availability.create_availability_rule(
        session=session,
        obj_in=obj_in,
        service_id=service_id
    )

@router.get("/services/{service_id}/availability", response_model=List[AvailabilityRuleOut])
def get_availability_rules(
    *,
    service_id: UUID,
    skip: int = 0,
    limit: int = 100,
    session: SessionDep,
    current_user: CurrentUser
) -> List[AvailabilityRuleOut]:
    """
    Get all availability rules for a service.
    """
    # Verify that the service belongs to the current user
    service = session.get(Service, service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    if service.account_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    return crud.availability.get_availability_rules_by_service(
        session=session,
        service_id=service_id,
        skip=skip,
        limit=limit
    )

@router.put("/availability/{rule_id}", response_model=AvailabilityRuleOut)
def update_availability_rule(
    *,
    rule_id: UUID,
    obj_in: AvailabilityRuleUpdate,
    session: SessionDep,
    current_user: CurrentUser
) -> AvailabilityRuleOut:
    """
    Update an availability rule.
    """
    # Get the rule and verify ownership
    rule = crud.availability.get_availability_rule(session=session, rule_id=rule_id)
    if not rule:
        raise HTTPException(status_code=404, detail="Availability rule not found")
    
    service = session.get(Service, rule.service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    if service.account_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    updated_rule = crud.availability.update_availability_rule(
        session=session,
        rule_id=rule_id,
        obj_in=obj_in
    )
    
    if not updated_rule:
        raise HTTPException(status_code=404, detail="Availability rule not found")
    
    return updated_rule

@router.delete("/availability/{rule_id}")
def delete_availability_rule(
    *,
    rule_id: UUID,
    session: SessionDep,
    current_user: CurrentUser
) -> None:
    """
    Delete an availability rule.
    """
    # Get the rule and verify ownership
    rule = crud.availability.get_availability_rule(session=session, rule_id=rule_id)
    if not rule:
        raise HTTPException(status_code=404, detail="Availability rule not found")
    
    service = session.get(Service, rule.service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    if service.account_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    crud.availability.delete_availability_rule(
        session=session,
        rule_id=rule_id
    ) 

    return {"message": "Availability rule deleted successfully"}

@router.patch("/availability/{rule_id}", response_model=AvailabilityRuleOut)
def patch_availability_rule(
    *,
    rule_id: UUID,
    obj_in: AvailabilityRuleUpdate,
    session: SessionDep,
    current_user: CurrentUser
) -> AvailabilityRuleOut:
    """
    Update specific fields of an availability rule.
    """
    # Get the rule and verify ownership
    rule = crud.availability.get_availability_rule(session=session, rule_id=rule_id)
    if not rule:
        raise HTTPException(status_code=404, detail="Availability rule not found")
    
    service = session.get(Service, rule.service_id)
    if not service:
        raise HTTPException(status_code=404, detail="Service not found")
    if service.account_id != current_user.id and not current_user.is_superuser:
        raise HTTPException(status_code=403, detail="Not enough permissions")
    
    updated_rule = crud.availability.update_availability_rule(
        session=session,
        rule_id=rule_id,
        obj_in=obj_in
    )
    
    if not updated_rule:
        raise HTTPException(status_code=404, detail="Availability rule not found")
    
    return updated_rule

@router.get("/availability/{rule_id}", response_model=AvailabilityRuleOut)
def get_availability_rule_by_id(
    *,
    rule_id: UUID,
    session: SessionDep,
    current_user: CurrentUser
) -> AvailabilityRuleOut:
    """
    Get a specific availability rule by ID.
    """
    # Get the rule and verify ownership
    rule = crud.availability.get_availability_rule(session=session, rule_id=rule_id)
    if not rule:
        raise HTTPException(status_code=404, detail="Availability rule not found")
    
    service = session.get(Service, rule.service_id)
    if not service or service.account_id != current_user.id:
        raise HTTPException(status_code=404, detail="Service not found")
    
    return rule