# services/inventory/app/api/food_safety_compliance.py
"""
Food Safety Compliance API - ATOMIC CRUD operations on FoodSafetyCompliance model
"""

from typing import List, Optional
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, Query, Path, status
from sqlalchemy.ext.asyncio import AsyncSession
import structlog

from shared.auth.decorators import get_current_user_dep
from shared.auth.access_control import require_user_role
from shared.routing import RouteBuilder
from app.core.database import get_db
from app.services.food_safety_service import FoodSafetyService
from app.models import AuditLog
from app.schemas.food_safety import (
    FoodSafetyComplianceCreate,
    FoodSafetyComplianceUpdate,
    FoodSafetyComplianceResponse
)

logger = structlog.get_logger()
route_builder = RouteBuilder('inventory')
router = APIRouter(tags=["food-safety-compliance"])


async def get_food_safety_service() -> FoodSafetyService:
    """Get food safety service instance"""
    return FoodSafetyService()


@router.post(
    route_builder.build_base_route("food-safety/compliance"),
    response_model=FoodSafetyComplianceResponse,
    status_code=status.HTTP_201_CREATED
)
@require_user_role(['admin', 'owner', 'member'])
async def create_compliance_record(
    compliance_data: FoodSafetyComplianceCreate,
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    food_safety_service: FoodSafetyService = Depends(get_food_safety_service),
    db: AsyncSession = Depends(get_db)
):
    """Create a new food safety compliance record"""
    try:
        compliance_data.tenant_id = tenant_id

        compliance = await food_safety_service.create_compliance_record(
            db,
            compliance_data,
            user_id=UUID(current_user["user_id"])
        )

        logger.info("Compliance record created",
                   compliance_id=str(compliance.id),
                   standard=compliance.standard)

        return compliance

    except ValueError as e:
        logger.warning("Invalid compliance data", error=str(e))
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail=str(e)
        )
    except Exception as e:
        logger.error("Error creating compliance record", error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to create compliance record"
        )


@router.get(
    route_builder.build_base_route("food-safety/compliance"),
    response_model=List[FoodSafetyComplianceResponse]
)
async def get_compliance_records(
    tenant_id: UUID = Path(...),
    ingredient_id: Optional[UUID] = Query(None, description="Filter by ingredient ID"),
    standard: Optional[str] = Query(None, description="Filter by compliance standard"),
    status_filter: Optional[str] = Query(None, description="Filter by compliance status"),
    skip: int = Query(0, ge=0, description="Number of records to skip"),
    limit: int = Query(100, ge=1, le=1000, description="Number of records to return"),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Get compliance records with filtering"""
    try:
        filters = {}
        if ingredient_id:
            filters["ingredient_id"] = ingredient_id
        if standard:
            filters["standard"] = standard
        if status_filter:
            filters["compliance_status"] = status_filter

        query = """
            SELECT * FROM food_safety_compliance
            WHERE tenant_id = :tenant_id AND is_active = true
        """
        params = {"tenant_id": tenant_id}

        if filters:
            for key, value in filters.items():
                query += f" AND {key} = :{key}"
                params[key] = value

        query += " ORDER BY created_at DESC LIMIT :limit OFFSET :skip"
        params.update({"limit": limit, "skip": skip})

        result = await db.execute(query, params)
        records = result.fetchall()

        return [
            FoodSafetyComplianceResponse(**dict(record))
            for record in records
        ]

    except Exception as e:
        logger.error("Error getting compliance records", error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve compliance records"
        )


@router.get(
    route_builder.build_resource_detail_route("food-safety/compliance", "compliance_id"),
    response_model=FoodSafetyComplianceResponse
)
async def get_compliance_record(
    compliance_id: UUID = Path(...),
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Get specific compliance record"""
    try:
        query = "SELECT * FROM food_safety_compliance WHERE id = :compliance_id AND tenant_id = :tenant_id"
        result = await db.execute(query, {"compliance_id": compliance_id, "tenant_id": tenant_id})
        record = result.fetchone()

        if not record:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Compliance record not found"
            )

        return FoodSafetyComplianceResponse(**dict(record))

    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error getting compliance record", error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to retrieve compliance record"
        )


@router.put(
    route_builder.build_resource_detail_route("food-safety/compliance", "compliance_id"),
    response_model=FoodSafetyComplianceResponse
)
@require_user_role(['admin', 'owner', 'member'])
async def update_compliance_record(
    compliance_data: FoodSafetyComplianceUpdate,
    tenant_id: UUID = Path(...),
    compliance_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    food_safety_service: FoodSafetyService = Depends(get_food_safety_service),
    db: AsyncSession = Depends(get_db)
):
    """Update an existing compliance record"""
    try:
        compliance = await food_safety_service.update_compliance_record(
            db,
            compliance_id,
            tenant_id,
            compliance_data,
            user_id=UUID(current_user["user_id"])
        )

        if not compliance:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Compliance record not found"
            )

        logger.info("Compliance record updated",
                   compliance_id=str(compliance.id))

        return compliance

    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error updating compliance record",
                    compliance_id=str(compliance_id),
                    error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to update compliance record"
        )


@router.delete(
    route_builder.build_resource_detail_route("food-safety/compliance", "compliance_id"),
    status_code=status.HTTP_403_FORBIDDEN
)
@require_user_role(['admin', 'owner'])
async def delete_compliance_record(
    compliance_id: UUID = Path(...),
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """
    Compliance records CANNOT be deleted for regulatory compliance.
    Use the archive endpoint to mark records as inactive.
    """
    raise HTTPException(
        status_code=status.HTTP_403_FORBIDDEN,
        detail={
            "error": "compliance_records_cannot_be_deleted",
            "message": "Compliance records cannot be deleted for regulatory compliance. Use PUT /food-safety/compliance/{id}/archive to archive records instead.",
            "reason": "Food safety compliance records must be retained for regulatory audits",
            "alternative_endpoint": f"/api/v1/tenants/{tenant_id}/inventory/food-safety/compliance/{compliance_id}/archive"
        }
    )


@router.put(
    route_builder.build_nested_resource_route("food-safety/compliance", "compliance_id", "archive"),
    response_model=dict
)
@require_user_role(['admin', 'owner'])
async def archive_compliance_record(
    compliance_id: UUID = Path(...),
    tenant_id: UUID = Path(...),
    current_user: dict = Depends(get_current_user_dep),
    db: AsyncSession = Depends(get_db)
):
    """Archive (soft delete) compliance record - marks as inactive but retains for audit"""
    try:
        query = """
            UPDATE food_safety_compliance
            SET is_active = false, updated_at = NOW(), updated_by = :user_id
            WHERE id = :compliance_id AND tenant_id = :tenant_id
        """
        result = await db.execute(query, {
            "compliance_id": compliance_id,
            "tenant_id": tenant_id,
            "user_id": UUID(current_user["user_id"])
        })

        if result.rowcount == 0:
            raise HTTPException(
                status_code=status.HTTP_404_NOT_FOUND,
                detail="Compliance record not found"
            )

        await db.commit()

        # Log audit event for archiving compliance record
        try:
            from shared.security import create_audit_logger, AuditSeverity, AuditAction
            audit_logger = create_audit_logger("inventory-service", AuditLog)
            await audit_logger.log_event(
                db_session=db,
                tenant_id=str(tenant_id),
                user_id=current_user["user_id"],
                action="archive",
                resource_type="compliance_record",
                resource_id=str(compliance_id),
                severity=AuditSeverity.HIGH.value,
                description=f"Archived compliance record (retained for regulatory compliance)",
                endpoint=f"/food-safety/compliance/{compliance_id}/archive",
                method="PUT"
            )
        except Exception as audit_error:
            logger.warning("Failed to log audit event", error=str(audit_error))

        return {
            "message": "Compliance record archived successfully",
            "compliance_id": str(compliance_id),
            "archived": True,
            "note": "Record retained for regulatory compliance audits"
        }

    except HTTPException:
        raise
    except Exception as e:
        logger.error("Error archiving compliance record", error=str(e))
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail="Failed to archive compliance record"
        )
