import re
import uuid
from typing import Annotated, Optional
from fastapi import APIRouter, File, Form, UploadFile, Depends, HTTPException, BackgroundTasks, Request
import structlog

from .models.responses import InsertMenuItemsResponse
from ...shared.middleware.auth import verify_insert_menu_items_auth
from ...shared.exceptions.base import ValidationException

router = APIRouter(prefix="/menu-items", tags=["insert_menu_items"])
logger = structlog.get_logger("insert_menu_items.routes")

# Service instance will be set by main.py
insert_menu_items_service = None


def set_insert_menu_items_service(service):
    """Set the insert_menu_items service instance"""
    global insert_menu_items_service
    insert_menu_items_service = service


@router.post(
    "/insert",
    response_model=InsertMenuItemsResponse,
    status_code=202,  # Accepted
    summary="Upload menu image and trigger async menu creation",
    dependencies=[Depends(verify_insert_menu_items_auth)]
)
async def insert_menu_items(
    request: Request,
    background_tasks: BackgroundTasks,
    file: Annotated[UploadFile, File(..., description="Menu image file")],
    city: Annotated[str, Form(..., description="City identifier (e.g., 'sofia')")],
    token: Annotated[str, Form(..., description="API token for createMenu.php")],
    zavedenia_id: Annotated[Optional[int], Form()] = None,
    zavedeniaId: Annotated[Optional[int], Form()] = None,
    zId: Annotated[Optional[int], Form()] = None,
    vanueName: Annotated[Optional[str], Form()] = None,
    source_language: Annotated[str, Form()] = "bg",
    target_language: Annotated[str, Form()] = "en",
) -> InsertMenuItemsResponse:
    """
    Upload menu image and trigger asynchronous menu extraction and creation.

    Returns immediately with 202 Accepted status.
    Menu processing happens in the background.

    Flow:
    1. Upload image → Immediate response (202)
    2. Background: Extract menu → Transform data → Call createMenu.php
    """

    # Generate unique request ID for tracking
    request_id = str(uuid.uuid4())
    form = await request.form()
    raw_form_fields = {
        key: str(value)
        for key, value in form.multi_items()
        if not hasattr(value, "filename")
    }

    def parse_optional_int(value: object) -> Optional[int]:
        if value is None:
            return None
        text = str(value).strip()
        if not text or text.lower() in {"none", "null", "undefined"}:
            return None
        try:
            return int(text)
        except ValueError:
            return None

    normalized_form_fields = {
        re.sub(r"[^a-z0-9]", "", key.lower()): value
        for key, value in raw_form_fields.items()
    }
    raw_zavedenia_candidates = [
        "zavedenia_id",
        "zavedeniaId",
        "zavedeniaID",
        "zavedeniaid",
        "zavedenie_id",
        "zavedenieId",
        "zavedenieID",
        "zavedenieid",
        "zId",
        "zID",
        "z_id",
        "restaurant_id",
        "restaurantId",
        "restaurantID",
        "restaurantid",
        "venue_id",
        "venueId",
        "venueID",
        "venueid",
    ]
    resolved_zavedenia_id = next(
        (
            value
            for value in (
                zavedenia_id,
                zavedeniaId,
                zId,
                *(
                    parse_optional_int(
                        raw_form_fields.get(key)
                        or normalized_form_fields.get(re.sub(r"[^a-z0-9]", "", key.lower()))
                    )
                    for key in raw_zavedenia_candidates
                ),
            )
            if value is not None
        ),
        -1,
    )

    logger.info(
        "insert_menu_items_request",
        request_id=request_id,
        filename=file.filename,
        city=city,
        zavedenia_id=resolved_zavedenia_id,
        vanue_name=vanueName or "",
        raw_zavedenia_id=zavedenia_id,
        raw_zavedeniaId=zavedeniaId,
        raw_zId=zId,
        raw_form_fields=raw_form_fields,
        normalized_form_field_keys=list(normalized_form_fields.keys()),
        source_language=source_language,
        target_language=target_language
    )

    try:
        logger.info(
            "VALIDATING_REQUEST",
            request_id=request_id,
            filename=file.filename,
            content_type=file.content_type
        )

        # Validate file
        if not file.content_type or not file.content_type.startswith("image/"):
            logger.error(
                "VALIDATION_FAILED",
                request_id=request_id,
                reason="invalid_content_type",
                content_type=file.content_type
            )
            raise ValidationException("Only image files are allowed")

        # Read file content
        image_content = await file.read()
        image_size = len(image_content)

        logger.info(
            "FILE_READ_SUCCESS",
            request_id=request_id,
            filename=file.filename,
            size_bytes=image_size,
            size_kb=round(image_size / 1024, 2)
        )

        if image_size == 0:
            logger.error(
                "VALIDATION_FAILED",
                request_id=request_id,
                reason="empty_file",
                filename=file.filename
            )
            raise ValidationException("Uploaded file is empty")

        # Add background task
        # Print equivalent curl command for this upload request
        from pathlib import Path
        from datetime import datetime

        # Construct the curl command
        base_url = "http://localhost:8000"  # This will be replaced with actual host in production
        endpoint = f"{base_url}/menu-items/insert"

        curl_command = (
            f"curl --location '{endpoint}' \\\n"
            f"--header 'Authorization: Bearer <YOUR_AUTH_KEY>' \\\n"
            f"--form 'file=@\"{file.filename}\"' \\\n"
            f"--form 'city=\"{city}\"' \\\n"
            f"--form 'zavedenia_id=\"{resolved_zavedenia_id}\"' \\\n"
            f"--form 'vanueName=\"{vanueName or ''}\"' \\\n"
            f"--form 'token=\"{token}\"' \\\n"
            f"--form 'source_language=\"{source_language}\"' \\\n"
            f"--form 'target_language=\"{target_language}\"'"
        )

        # Print to console
        print("\n" + "="*80)
        print("📥 EQUIVALENT CURL COMMAND FOR UPLOAD REQUEST")
        print("="*80)
        print(f"Request ID: {request_id}")
        print(f"Filename: {file.filename}")
        print(f"City: {city}")
        print(f"Zavedenia ID: {resolved_zavedenia_id}")
        print("\nYou can run this command manually to test:\n")
        print(curl_command)
        print("\n" + "="*80 + "\n")

        # Write to dedicated curl log file
        log_dir = Path("logs")
        log_dir.mkdir(exist_ok=True)
        curl_log_file = log_dir / "curl_commands.log"

        timestamp = datetime.now().isoformat()
        with open(curl_log_file, "a", encoding="utf-8") as f:
            f.write("\n" + "="*80 + "\n")
            f.write(f"📥 UPLOAD REQUEST\n")
            f.write(f"Timestamp: {timestamp}\n")
            f.write(f"Request ID: {request_id}\n")
            f.write(f"Filename: {file.filename}\n")
            f.write(f"City: {city}\n")
            f.write(f"Zavedenia ID: {resolved_zavedenia_id}\n")
            f.write("="*80 + "\n")
            f.write(curl_command + "\n")
            f.write("="*80 + "\n\n")

        logger.info(
            "UPLOAD_CURL_COMMAND",
            request_id=request_id,
            curl_command=curl_command,
            curl_log_file=str(curl_log_file)
        )

        logger.info(
            "SCHEDULING_BACKGROUND_TASK",
            request_id=request_id,
            city=city,
            zavedenia_id=resolved_zavedenia_id,
            vanue_name=vanueName or "",
            source_language=source_language,
            target_language=target_language
        )

        background_tasks.add_task(
            insert_menu_items_service.process_menu_upload,
            image_content=image_content,
            filename=file.filename,
            mime_type=file.content_type,
            city=city,
            zavedenia_id=resolved_zavedenia_id,
            vanue_name=vanueName or "",
            token=token,
            source_language=source_language,
            target_language=target_language,
            request_id=request_id,
            raw_form_fields=raw_form_fields,
        )

        logger.info(
            "REQUEST_ACCEPTED_202",
            request_id=request_id,
            city=city,
            filename=file.filename,
            background_task_scheduled=True
        )

        return InsertMenuItemsResponse(
            status="processing",
            message="Image uploaded successfully. Menu extraction and creation in progress.",
            request_id=request_id
        )

    except ValidationException as e:
        logger.error(
            "insert_menu_items_validation_error",
            request_id=request_id,
            error=str(e)
        )
        raise HTTPException(status_code=400, detail=str(e.message))

    except Exception as e:
        logger.error(
            "insert_menu_items_error",
            request_id=request_id,
            error=str(e)
        )
        raise HTTPException(status_code=500, detail=f"Failed to process request: {str(e)}")
