from typing import Optional
from uuid import UUID
from datetime import datetime
import logging
from fastapi import APIRouter, Depends, HTTPException, Query, status
from sqlalchemy.ext.asyncio import AsyncSession

from app.api import deps
from app.schemas.violation import (
    ViolationCreate,
    ViolationUpdate,
    ViolationResponse,
    ViolationListResponse,
)
from app.services.violation_service import ViolationService

router = APIRouter()
logger = logging.getLogger(__name__)


@router.post("/", response_model=ViolationResponse, status_code=status.HTTP_201_CREATED)
async def create_violation(
    violation_in: ViolationCreate,
    db: AsyncSession = Depends(deps.get_db),
    current_user=Depends(deps.get_current_user),
):
    """
    Create a new violation record. (Admin only)
    
    **Request Body:**
    - `product_name`: Name of the product
    - `msp`: Manufacturer Suggested Price
    - `scraped_price`: Price found during scraping
    - `url`: URL where the violation was found
    - `violation_date`: Date of the violation
    - `vendor_id`: (Optional) Associated vendor ID
    - `barcode_number`: (Optional) Product barcode
    - `reference_id`: (Optional) Reference identifier
    - `source_type`: (Optional) 'registered' or 'discovered' (default: 'registered')
    """
    violation = await ViolationService.create_violation(db, violation_in)
    return violation


@router.get("/", response_model=ViolationListResponse)
async def get_violations(
    db: AsyncSession = Depends(deps.get_db),
    page: int = Query(1, ge=1, description="Page number"),
    limit: int = Query(10, ge=1, le=100, description="Items per page"),
    sort_by: str = Query(
        "violation_date",
        regex="^(violation_date|created_at|product_name|price_difference|percentage_difference|vendor_name)$",
        description="Field to sort by"
    ),
    sort_order: str = Query(
        "desc",
        regex="^(asc|desc)$",
        description="Sort order: asc (A-Z/oldest first) or desc (Z-A/newest first)"
    ),
    product_name: Optional[str] = Query(None, description="Search by product name"),
    search: Optional[str] = Query(None, description="Global search across product name, vendor name, marketplace, and URL"),
    vendor_name: Optional[str] = Query(None, description="Search by vendor name"),
    marketplace: Optional[str] = Query(None, description="Search by marketplace"),
    url: Optional[str] = Query(None, description="Search by URL"),
    vendor_id: Optional[UUID] = Query(None, description="Filter by vendor ID"),
    source_type: Optional[str] = Query(
        None,
        regex="^(registered|discovered)$",
        description="Filter by source type"
    ),
    violation_status: Optional[str] = Query(
        None,
        regex="^(open|notified)$",
        description="Filter by violation status (open or notified)"
    ),
    date_from: Optional[datetime] = Query(None, description="Filter from this date"),
    date_to: Optional[datetime] = Query(None, description="Filter until this date"),
    current_user=Depends(deps.get_current_user),
):
    """
    Retrieve a list of all violations with pagination, sorting, and filtering.
    
    **Query Parameters:**
    - `page`: Page number (default: 1)
    - `limit`: Items per page (default: 10, max: 100)
    - `sort_by`: Sort field - violation_date, created_at, product_name, price_difference, percentage_difference, or vendor_name
    
    **Search Parameters (dynamic, partial match):**
    - `product_name`: Search by product name
    - `search`: Search by product name (alternative/legacy parameter)
    - `vendor_name`: Search by vendor name
    - `marketplace`: Search by marketplace (e.g., Amazon, eBay, Flipkart)
    - `url`: Search by URL
    
    **Filter Parameters:**
    - `vendor_id`: Filter by specific vendor ID
    - `source_type`: Filter by source (registered or discovered)
    - `violation_status`: Filter by status (open or notified)
    - `date_from`: Filter violations from this date (inclusive)
    - `date_to`: Filter violations until this date (inclusive)
    """
    violations, total = await ViolationService.get_violations(
        db,
        page=page,
        limit=limit,
        sort_by=sort_by,
        sort_order=sort_order,
        product_name=product_name,
        search=search,
        vendor_name=vendor_name,
        marketplace=marketplace,
        url=url,
        vendor_id=vendor_id,
        source_type=source_type,
        violation_status=violation_status,
        date_from=date_from,
        date_to=date_to,
    )
    
    return ViolationListResponse(items=violations, total=total, page=page, limit=limit)


@router.get("/statistics", response_model=dict)
async def get_violation_statistics(
    db: AsyncSession = Depends(deps.get_db),
    current_user=Depends(deps.get_current_user),
):
    """
    Get statistics about violations including:
    - Total violation count
    - Count by source type (registered vs discovered)
    - Average price difference
    - Average percentage difference
    """
    stats = await ViolationService.get_statistics(db)
    return stats


@router.get("/vendor/{vendor_id}", response_model=ViolationListResponse)
async def get_vendor_violations(
    vendor_id: UUID,
    db: AsyncSession = Depends(deps.get_db),
    page: int = Query(1, ge=1),
    limit: int = Query(10, ge=1, le=100),
    current_user=Depends(deps.get_current_user),
):
    """
    Get all violations associated with a specific vendor.
    """
    violations, total = await ViolationService.get_violations_by_vendor(
        db, vendor_id=vendor_id, page=page, limit=limit
    )
    
    return ViolationListResponse(items=violations, total=total, page=page, limit=limit)


@router.get("/{violation_id}", response_model=ViolationResponse)
async def get_violation(
    violation_id: UUID,
    db: AsyncSession = Depends(deps.get_db),
    current_user=Depends(deps.get_current_user),
):
    """
    Retrieve a single violation by its ID with vendor information.
    """
    violation = await ViolationService.get_violation_by_id(db, violation_id)
    return violation


@router.put("/{violation_id}", response_model=ViolationResponse)
async def update_violation(
    violation_id: UUID,
    violation_in: ViolationUpdate,
    db: AsyncSession = Depends(deps.get_db),
    current_user=Depends(deps.get_current_user),
):
    """
    Update an existing violation. (Admin only)
    """
    violation = await ViolationService.update_violation(db, violation_id, violation_in)
    return violation


@router.delete("/{violation_id}", response_model=dict)
async def delete_violation(
    violation_id: UUID,
    db: AsyncSession = Depends(deps.get_db),
    current_user=Depends(deps.get_current_user),
):
    """
    Delete a violation record. (Admin only)
    """
    await ViolationService.delete_violation(db, violation_id)
    return {"message": "Violation deleted successfully"}
