from typing import List, Optional, Annotated
from fastapi import APIRouter, Depends, Query, HTTPException, Form, UploadFile, File, Path
from pydantic import EmailStr
from sqlalchemy.ext.asyncio import AsyncSession

from src.manufacturer.models import ManufacturerStatus
from src.utils.image_manager import handle_image_upload
from src.manufacturer.schemas import ManufacturerResponse, ManufacturerCreateForm, ManufacturerOutSchema, \
    ManufacturerListResponse, ManufacturerPhotoResponse
from src.manufacturer.service import ManufacturerService
from src.database import get_db
router = APIRouter(prefix="/manufacturer", tags=["Manufacturer"])

@router.get("", response_model=ManufacturerListResponse)
async def list_manufacturers(
        needle: Optional[str] = Query(None),
        sort_field: str = Query("date_added", alias="sort[field]", description="Sort by date_added, name, rating, date_modify"),
        sort_order: str = Query("DESC", alias="sort[order]", description="DESC, ASC"),
        page: int = Query(1, ge=1),
        limit: int = Query(10, ge=1),
        db: AsyncSession = Depends(get_db),
):
    result = await ManufacturerService.get_manufacturers_list(
        db=db, needle=needle, sort_field=sort_field,
        sort_order=sort_order, page=page, limit=limit
    )
    return {
        "data": result["items"],
        "total": result["total"],
        "page": page,
        "limit": limit,
        "status": True
    }

@router.get("/{manufacturer_id}")
async def get_manufacturer(
    manufacturer_id: int,
    db: AsyncSession = Depends(get_db),
):
    manufacturer = await ManufacturerService.get_manufacturer_by_id(db, manufacturer_id)
    return {"data": manufacturer, "status": True}

from datetime import datetime
from typing import Optional, Annotated

from fastapi import APIRouter, Depends, Form, File, UploadFile, HTTPException
from pydantic import EmailStr
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy import select

@router.post("", response_model=ManufacturerResponse, status_code=201)
async def create_manufacturer(
    name: Annotated[str, Form()],
    address: Annotated[Optional[str], Form()] = None,
    description: Annotated[Optional[str], Form()] = None,
    phone: Annotated[Optional[str], Form()] = None,
    email: Annotated[Optional[EmailStr], Form()] = None,
    status: Annotated[Optional[int], Form()] = ManufacturerStatus.OFF.value,
    seo_keyword: Annotated[Optional[str], Form()] = None,
    meta_title: Annotated[Optional[str], Form()] = None,
    meta_description: Annotated[Optional[str], Form()] = None,
    meta_keyword: Annotated[Optional[str], Form()] = None,
    logo: Optional[UploadFile] = File(None),
    db: AsyncSession = Depends(get_db),
):
    # Перевірка статусу
    status = status if status is not None else ManufacturerStatus.OFF.value
    if status not in (0, 1):
        raise HTTPException(status_code=400, detail="Invalid status value, only 0 or 1 allowed")

    # Формування даних
    data = ManufacturerCreateForm(
        name=name,
        address=address,
        description=description,
        phone=phone,
        email=email,
        status=status,
        seo_keyword=seo_keyword,
        meta_title=meta_title,
        meta_description=meta_description,
        meta_keyword=meta_keyword,
    )

    # Завантаження зображення
    logo_url = await handle_image_upload(logo) if logo else None

    # Виклик сервісу
    new_manufacturer = await ManufacturerService.create_manufacturer(
        db=db, data=data, logo_url=logo_url
    )
    return new_manufacturer


@router.patch("/{manufacturer_id}")
async def update_manufacturer(
    manufacturer_id: int = Path(...),
    name: Optional[str] = Form(None),
    address: Optional[str] = Form(None),
    description: Optional[str] = Form(None),
    phone: Optional[str] = Form(None),
    email: Optional[EmailStr] = Form(None),
    status: Optional[int] = Form(None),
    seo_keyword: Optional[str] = Form(None),
    meta_title: Optional[str] = Form(None),
    meta_description: Optional[str] = Form(None),
    meta_keyword: Optional[str] = Form(None),
    logo: Optional[UploadFile] = File(None),
    db: AsyncSession = Depends(get_db),
):
    update_data = {
        "name": name,
        "address": address,
        "description": description,
        "phone": phone,
        "email": email,
        "seo_keyword": seo_keyword,
        "meta_title": meta_title,
        "meta_description": meta_description,
        "meta_keyword": meta_keyword,
    }

    # Валідація status
    if status is not None:
        try:
            status_int = int(status)
        except ValueError:
            raise HTTPException(status_code=400, detail="Status must be 0 or 1")
        if status_int not in [0, 1]:
            raise HTTPException(status_code=400, detail="Invalid status value, used only 0 or 1")
        update_data["status"] = status_int

    update_data = {k: v for k, v in update_data.items() if v is not None}

    logo_url = None
    if logo is not None:
        logo_url = await handle_image_upload(logo)

    try:
        updated = await ManufacturerService.update_manufacturer(
            db=db,
            manufacturer_id=manufacturer_id,
            update_data=update_data,
            logo_url=logo_url
        )
        return {"data": updated, "status": True}
    except Exception as e:
        return {"data": None, "status": False, "message": str(e)}

@router.post("/{manufacturer_id}/photo", status_code=201)
async def upload_manufacturer_photo(
        manufacturer_id: int = Path(..., description="Manufacturer ID"),
        file: UploadFile = File(..., description="Manufacturer Photo"),
        db: AsyncSession = Depends(get_db)
):
    try:
        image_url = await handle_image_upload(file)

        photo = await ManufacturerService.add_manufacturer_photo(
            db=db,
            manufacturer_id=manufacturer_id,
            image_url=image_url
        )
        return {
            "data": ManufacturerPhotoResponse.model_validate(photo),
            "status": True
        }
    except HTTPException as http_exc:
        raise http_exc
    except Exception as e:
        return {
            "data": None,
            "status": False,
            "message": str(e)
        }

@router.get("/{manufacturer_id}/photo")
async def get_manufacturer_photo(
    manufacturer_id: int = Path(..., description="Manufacturer ID"),
    page: int = Query(1, ge=1, description="Page number"),
    limit: int = Query(10, ge=1, le=100, description="Items per page"),
    db: AsyncSession = Depends(get_db)
):
    photos, total = await ManufacturerService.get_manufacturer_photo(
        manufacturer_id=manufacturer_id, db=db, page=page, limit=limit
    )
    return {
        "data": [ManufacturerPhotoResponse.model_validate(photo) for photo in photos],
        "status": True,
        "page": page,
        "limit": limit,
        "total": total,
    }

@router.delete("/{manufacturer_id}/photo/{manufacturer_photo_id}")
async def delete_manufacturer_photo(
        manufacturer_id: int = Path(..., description="Manufacturer ID"),
        manufacturer_photo_id: str = Path(..., description="Manufacturer Photo ID"),
        db: AsyncSession = Depends(get_db)
):
    try:
         await ManufacturerService.delete_manufacturer_photo(
             db=db,
             manufacturer_id=manufacturer_id,
             manufacturer_photo_id=manufacturer_photo_id
         )
         return {"data": "Manufacturer photo deleted", "status": True}
    except HTTPException as http_exc:
        raise http_exc
    except Exception as e:
        return {
            "data": None,
            "status": False,
            "message": str(e)
        }

@router.delete("/{manufacturer_id}")
async def delete_manufacturer(
    manufacturer_id: int,
    db: AsyncSession = Depends(get_db),
):
        await ManufacturerService.delete_manufacturer(db, manufacturer_id)
        return {
            "data": {"message": "Manufacturer deleted"},
            "status": True
        }
