from typing import List

from core.database import get_core_db
from core.security import get_current_user
from fastapi import APIRouter, Depends, HTTPException, status
from sqlalchemy.orm import Session

from .dto import FractionRuleOctaveCreateDTO, FractionRuleOctaveResponseDTO
from .services import FractionRuleOctaveService

router = APIRouter(prefix="/fraction_rule_octave")


@router.get("/", response_model=List[FractionRuleOctaveResponseDTO])
async def list_fractions(
    db: Session = Depends(get_core_db), current_user: dict = Depends(get_current_user)
):
    """
    List all FractionRuleOctave entries.
    """
    # Validate access to the tenant and company
    tenant_id = current_user.get("tenant_id")
    company_id = current_user.get("company_id")

    if not tenant_id or not company_id:
        raise HTTPException(
            status_code=403, detail="Access denied: Tenant or Company not found"
        )

    return db.query(FractionRuleOctaveService).all()


@router.get(
    "/{permission}/{line}/{fraction}", response_model=FractionRuleOctaveResponseDTO
)
async def read_fraction(
    permission: str,
    line: int,
    fraction: str,
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """
    Get a specific FractionRuleOctave by its composite key.
    """
    # Validate access to the tenant and company
    tenant_id = current_user.get("tenant_id")
    company_id = current_user.get("company_id")

    if not tenant_id or not company_id:
        raise HTTPException(
            status_code=403, detail="Access denied: Tenant or Company not found"
        )

    frac = FractionRuleOctaveService.get_fraction_by_permission_line(
        db, permission, line, fraction
    )
    if not frac:
        raise HTTPException(status_code=404, detail="FractionRuleOctave not found")
    return frac


@router.post(
    "/",
    response_model=FractionRuleOctaveResponseDTO,
    status_code=status.HTTP_201_CREATED,
)
async def create_frac(
    frac_data: FractionRuleOctaveCreateDTO,
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """
    Create a new FractionRuleOctave entry.
    """
    # Validate access to the tenant and company
    tenant_id = current_user.get("tenant_id")
    company_id = current_user.get("company_id")

    if not tenant_id or not company_id:
        raise HTTPException(
            status_code=403, detail="Access denied: Tenant or Company not found"
        )

    return FractionRuleOctaveService.create_frac(db, frac_data)


@router.delete(
    "/{permission}/{line}/{fraction}", status_code=status.HTTP_204_NO_CONTENT
)
async def delete_fraction(
    permission: str,
    line: int,
    fraction: str,
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """
    Delete a FractionRuleOctave by its composite key.
    """
    # Validate access to the tenant and company
    tenant_id = current_user.get("tenant_id")
    company_id = current_user.get("company_id")

    if not tenant_id or not company_id:
        raise HTTPException(
            status_code=403, detail="Access denied: Tenant or Company not found"
        )

    frac = FractionRuleOctaveService.delete_fraction(db, permission, line, fraction)
    if not frac:
        raise HTTPException(status_code=404, detail="FractionRuleOctave not found")
