from fastapi import APIRouter, Depends, HTTPException, status, UploadFile, File, Request
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import List
import json
from slowapi import Limiter
from slowapi.util import get_remote_address
from .. import models, schemas, auth
from ..database import get_db

# [H-02] Rate limiter for extract-label endpoint
limiter = Limiter(key_func=get_remote_address)

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

@router.get("/stats")
def read_item_stats(
    db: Session = Depends(get_db),
    current_user: auth.TokenData = Depends(auth.get_current_user)
):
    """[C-01] Item statistics — only for authenticated users."""
    total_categories = db.query(models.Category).count()
    total_items = db.query(models.Item).count()

    # Count items per category string
    items_per_category = db.query(models.Item.category, func.count(models.Item.id))\
        .group_by(models.Item.category).all()

    return {
        "total_categories": total_categories,
        "total_items": total_items,
        "items_distribution": {cat: count for cat, count in items_per_category if cat}
    }

@router.get("/", response_model=List[schemas.Item])
def read_items(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db),
    current_user: auth.TokenData = Depends(auth.get_current_user)
):
    """[C-01] List of items — only for authenticated users."""
    items = db.query(models.Item).offset(skip).limit(limit).all()
    return items

@router.get("/{item_id}", response_model=schemas.Item)
def read_item(
    item_id: int,
    db: Session = Depends(get_db),
    current_user: auth.TokenData = Depends(auth.get_current_user)
):
    """[C-01] Get item — only for authenticated users."""
    item = db.query(models.Item).filter(models.Item.id == item_id).first()
    if item is None:
        raise HTTPException(status_code=404, detail="Item not found")
    return item

_ALLOWED_IMAGE_TYPES = {"image/jpeg", "image/png", "image/webp", "image/gif"}
_MAX_IMAGE_SIZE = 10 * 1024 * 1024  # 10 MB

@limiter.limit("10/minute")
@router.post("/extract-label")
async def extract_label(
    request: Request,
    file: UploadFile = File(...),
    mode: str = "item", # 'item' or 'box'
    current_user: auth.TokenData = Depends(auth.get_current_user)
):
    """[C-01] Extract label from image — only for authenticated users. [H-02] Rate limit: 10 req/min per IP."""
    from ..ai_vision import extract_label_info

    # [SECURITY FIX H-03] Validate MIME type and maximum size
    if file.content_type not in _ALLOWED_IMAGE_TYPES:
        raise HTTPException(
            status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
            detail=f"File type not allowed: {file.content_type}. Accepted: {', '.join(_ALLOWED_IMAGE_TYPES)}"
        )

    contents = await file.read()

    if len(contents) > _MAX_IMAGE_SIZE:
        raise HTTPException(
            status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
            detail="File exceeds 10MB limit."
        )

    result = extract_label_info(contents, mode=mode)
    return result

@router.post("/", response_model=schemas.Item, status_code=status.HTTP_201_CREATED)
def create_item(
    item: schemas.ItemCreate,
    db: Session = Depends(get_db),
    current_user: auth.TokenData = Depends(auth.get_current_user)
):
    """[C-01] Create item — only for authenticated users. [M-02] user_id from token."""
    # Check if barcode exists
    db_item = db.query(models.Item).filter(models.Item.barcode == item.barcode).first()
    if db_item:
        raise HTTPException(status_code=400, detail="Barcode already registered")

    db_item = models.Item(**item.model_dump())
    db.add(db_item)
    db.commit()
    db.refresh(db_item)

    # Audit log the creation — [M-02] user_id from token, not from body
    # Capture full snapshot
    item_snapshot = {
        "barcode": db_item.barcode,
        "name": db_item.name,
        "category": db_item.category,
        "type": db_item.type,
        "part_number": db_item.part_number,
        "color": db_item.color,
        "specs": db_item.specs,
        "box_label": db_item.box_label,
        "image_url": db_item.image_url
    }

    audit = models.AuditLog(
        user_id=current_user.sub,
        action="CREATE_ITEM",
        target_item_id=db_item.id,
        target_item_name=db_item.name,
        target_item_pn=db_item.part_number,
        target_item_barcode=db_item.barcode,
        target_snapshot=json.dumps(item_snapshot),
        quantity_change=item.quantity
    )
    db.add(audit)
    db.commit()

    return db_item

@router.put("/{item_id}", response_model=schemas.Item)
def update_item(
    item_id: int,
    item: schemas.ItemCreate,
    db: Session = Depends(get_db),
    current_user: auth.TokenData = Depends(auth.get_current_user)
):
    """[C-01] Update item — only for authenticated users."""
    db_item = db.query(models.Item).filter(models.Item.id == item_id).first()
    if not db_item:
        raise HTTPException(status_code=404, detail="Item not found")

    update_data = item.model_dump(exclude_unset=True)
    for key, value in update_data.items():
        setattr(db_item, key, value)

    db.commit()
    db.refresh(db_item)
    return db_item

@router.delete("/{item_id}")
def delete_item(
    item_id: int,
    db: Session = Depends(get_db),
    current_user: auth.TokenData = Depends(auth.get_current_admin)
):
    """[C-01] Delete item — only for authenticated users. InterventionItems are cleared; AuditLogs are KEPT for history."""
    db_item = db.query(models.Item).filter(models.Item.id == item_id).first()
    if not db_item:
        raise HTTPException(status_code=404, detail="Item not found")

    # [AUDIT] Log the deletion to database and disk
    from ..logger import log
    log.warning(f"USER[{current_user.sub}] DELETING ITEM: ID={item_id}, Name={db_item.name}, PN={db_item.part_number}")

    item_snapshot = {
        "barcode": db_item.barcode,
        "name": db_item.name,
        "category": db_item.category,
        "type": db_item.type,
        "part_number": db_item.part_number,
        "color": db_item.color,
        "specs": db_item.specs,
        "box_label": db_item.box_label,
        "image_url": db_item.image_url,
        "final_quantity": db_item.quantity
    }

    audit = models.AuditLog(
        user_id=current_user.sub,
        action="DELETE_ITEM",
        target_item_id=item_id,
        target_item_name=db_item.name,
        target_item_pn=db_item.part_number,
        target_item_barcode=db_item.barcode,
        target_snapshot=json.dumps(item_snapshot),
        details=f"Final Quantity: {db_item.quantity}"
    )
    db.add(audit)

    # [CLEANUP] Delete related InterventionItems to prevent foreign key issues
    db.query(models.InterventionItem).filter(models.InterventionItem.item_id == item_id).delete()
    
    # Audit Logs in database are NOT deleted here to preserve history of actions
    db.delete(db_item)
    db.commit()
    return {"message": "Item deleted successfully. History logs preserved."}
