"""
API Endpoints for Items management
Handles CRUD operations for Item with one-to-many relationships to LineItems
"""

from typing import Dict, Any, Optional
from fastapi import APIRouter, Depends, HTTPException, Query, Path, status
from sqlalchemy.orm import Session

from core.database import get_core_db
from core.security import get_current_user, validate_access_to_resource

from .schemas import (
    LineItemCreate,
    LineItemUpdate,    
    LineItemResponse,
    LineItemListResponse,
)
from .service import ItemService

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


# ============================================================================
# ITEM CRUD ENDPOINTS
# ============================================================================

@router.post("/", response_model=LineItemResponse, status_code=status.HTTP_201_CREATED)
async def create_item(
    item_data: LineItemCreate,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    Create a new item with multiple line items and their nested data

    The item follows a one-to-many relationship structure:
    - Each LineItem has one LineFinancial
    - Each LineItem has one LineQuantity
    - Each LineItem has one LineCustoms
    - Each LineItem has one LineDescription
    - Each LineItem has one LineReference
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    service = ItemService()
    return service.create(db, item_data, tenant_id, company_id)


@router.get("/{item_id}", response_model=LineItemResponse)
async def get_item(
    item_id: int = Path(..., description="Item ID"),
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    Get a specific item by ID with all nested data
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    service = ItemService()
    item = service.get_by_id(db, item_id, tenant_id, company_id)

    if not item:
        raise HTTPException(status_code=404, detail="Item not found")

    return item


@router.get("/", response_model=LineItemListResponse)
async def list_items(
    company_id: int = Query(..., description="Company ID"),
    skip: int = Query(0, ge=0, description="Number of records to skip"),
    limit: int = Query(100, ge=1, le=1000,
                       description="Maximum records to return"),
    invoice_id: Optional[int] = Query(
        None, description="Filter by invoice ID"),
    item_type: Optional[str] = Query(None, description="Filter by item type"),
    system_origin: Optional[str] = Query(
        None, description="Filter by system origin (SCAF/SCAII)"),
    search: Optional[str] = Query(
        None, description="Search term for invoice number, reference, order, or guide"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    List items with optional filtering and pagination

    Filters:
    - invoice_id: Filter by specific invoice
    - item_type: Filter by item type (IMPORT_TEMP, IMPORT_DEF, EXPORT, REPAIR)
    - system_origin: Filter by system (SCAF, SCAII)
    - search: Search across multiple fields
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    service = ItemService()

    filters = {
        "invoice_id": invoice_id,
        "item_type": item_type,
        "system_origin": system_origin,
        "search": search,
    }

    items, total = service.get_all(
        db, tenant_id, company_id, skip, limit, filters)

    return LineItemListResponse(
        total=total,
        items=items,
        skip=skip,
        limit=limit
    )


@router.put("/{item_id}", response_model=LineItemResponse)
async def update_item(
    item_id: int = Path(..., description="Item ID"),
    item_data: LineItemUpdate = ...,
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    Update an item and optionally its nested line data
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    # Verify the item exists and belongs to the tenant/company
    service = ItemService()
    existing_item = service.get_by_id(db, item_id, tenant_id, company_id)
    if not existing_item:
        raise HTTPException(status_code=404, detail="Item not found")

    return service.update(db, item_id, item_data, tenant_id, company_id)


@router.delete("/{item_id}", status_code=status.HTTP_204_NO_CONTENT)
async def delete_item(
    item_id: int = Path(..., description="Item ID"),
    company_id: int = Query(..., description="Company ID"),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    Delete an item and all its related data (cascade delete)
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    service = ItemService()
    # Verify the item exists and belongs to the tenant/company
    existing_item = service.get_by_id(db, item_id, tenant_id, company_id)
    if not existing_item:
        raise HTTPException(status_code=404, detail="Item not found")

    success = service.delete(db, item_id, tenant_id, company_id)
    if not success:
        raise HTTPException(status_code=404, detail="Item not found")

    return None


# ============================================================================
# ADDITIONAL ENDPOINTS FOR INVOICE
# ============================================================================

@router.get("/invoice/{invoice_id}/items", response_model=LineItemListResponse)
async def get_items_by_invoice(
    invoice_id: int = Path(..., description="Invoice ID"),
    company_id: int = Query(..., description="Company ID"),
    skip: int = Query(0, ge=0),
    limit: int = Query(100, ge=1, le=1000),
    db: Session = Depends(get_core_db),
    current_user: Dict[str, Any] = Depends(get_current_user),
):
    """
    Get all items for a specific invoice
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    service = ItemService()
    items, total = service.get_by_invoice(
        db, invoice_id, tenant_id, company_id, skip, limit)

    return LineItemListResponse(
        total=total,
        items=items,
        skip=skip,
        limit=limit
    )
# STATISTICS & UTILITIES
# ============================================================================


@router.get("/stats/summary")
async def get_items_summary(
    company_id: int = Query(..., description="Company ID"),
    invoice_id: Optional[int] = Query(
        None, description="Filter by invoice ID"),
    db: Session = Depends(get_core_db),
    current_user: dict = Depends(get_current_user),
):
    """
    Get summary statistics for items
    """
    tenant_id = validate_access_to_resource(db, company_id, current_user)

    filters = {"invoice_id": invoice_id} if invoice_id else None
    items, total = ItemService.get_all(
        db=db,
        tenant_id=tenant_id,
        company_id=company_id,
        skip=0,
        limit=10000,  # Get all for stats
        filters=filters
    )

    # Calculate stats
    stats = {
        "total_items": total,
        "by_type": {},
        "by_system": {},
    }

    for item in items:
        # Count by type
        if item.item_type:
            stats["by_type"][item.item_type] = stats["by_type"].get(
                item.item_type, 0) + 1

        # Count by system
        if item.system_origin:
            stats["by_system"][item.system_origin] = stats["by_system"].get(
                item.system_origin, 0) + 1

    return stats
