from typing import Optional, List

from fastapi import APIRouter, Form, UploadFile, Depends, Path, Query, File, Request
from sqlalchemy.ext.asyncio import AsyncSession
from src.auth.schemas import LoginRequest
from src.auth.service import AuthService

from src.customer.schemas import CustomerCreate, CustomerResponseWrapper, CustomerListResponseWrapper, CustomerUpdate, \
    CustomerListResponse, CreateCustomerResponse, CustomerResponse
from src.customer.service import CustomerService
from src.database import get_db
from src.utils.google import generate_google_oauth_redirect_uri, get_customer_information_by_code


router = APIRouter(prefix="/customer", tags=["Customer"])

@router.post("", response_model=dict)
async def add_customer(
    name: str = Form(...),
    phone: str = Form(...),
    password: str = Form(...),
    comment: str = Form(None),
    logo: UploadFile = File(None),
    db: AsyncSession = Depends(get_db)
):
    data = CustomerCreate(
        name=name,
        phone=phone,
        password=password,
        comment=comment,
    )
    customer = await CustomerService.create_customer(db, data, logo)

    response_data = CustomerResponse.from_orm(customer)

    return {
        "data": response_data,
        "status": True
    }

@router.get("/{customer_id}", response_model=CustomerResponseWrapper)
async def get_customer_by_id(
        customer_id: int = Path(..., description="The customer id"),
        db: AsyncSession = Depends(get_db)
):
    return await CustomerService.get_customer_by_id(db, customer_id)


ALLOWED_SORT_FIELDS = ["id", "name", "last_action"]

@router.get("", response_model=CustomerListResponse)
async def list_customers(
    needle: Optional[str] = Query(None, description="Пошуковий рядок для фільтрації клієнтів"),
    status: Optional[bool] = Query(
        None,
        description="Фільтрація за статусом блокування клієнта (True = заблокований, False = активний)"
    ),
    date_start: Optional[str] = Query(
        None,
        description="Дата початку діапазону (формат YYYY-MM-DD)",
        example="2025-01-01"
    ),
    date_end: Optional[str] = Query(
        None,
        description="Дата кінця діапазону (формат YYYY-MM-DD)",
        example="2025-01-31"
    ),
    sort_field: str = Query(
        "customer_id",
        regex="^(customer_id|name|date_added)$",
        description="Поле для сортування: 'customer_id', 'name' або 'date_added'"
    ),
    sort_order: str = Query(
        "ASC",
        regex="^(ASC|DESC|asc|desc)$",
        description="Напрям сортування: 'ASC' - за зростанням, 'DESC' - за спаданням"
    ),
    page: int = Query(1, ge=1, description="Номер сторінки"),
    limit: int = Query(10, ge=1, description="Кількість записів на сторінці"),
    db: AsyncSession = Depends(get_db),
):
    try:
        date_range = None
        if date_start and date_end:
            date_range = [date_start, date_end]

        result = await CustomerService.get_customers_list(
            db=db,
            needle=needle,
            status=status,
            date_range=date_range,
            sort_field=sort_field,
            sort_order=sort_order,
            page=page,
            limit=limit
        )

        return {
            "data": result["items"],
            "dashboard": result.get("dashboard"),
            "total": result["total"],
            "page": page,
            "limit": limit,
            "status": True
        }

    except Exception as e:
        return {
            "data": [],
            "dashboard": None,
            "total": 0,
            "page": page,
            "limit": limit,
            "status": False,
            "message": str(e)
        }


@router.patch("/{customer_id}")
async def update_customer(
        customer_id: int = Path(..., description="The customer id"),
        update_data: CustomerUpdate = Depends(),
        logo: Optional[UploadFile] = File(None),
        db: AsyncSession = Depends(get_db),
):
    return await CustomerService.update_customer_by_id(
        db=db,
        customer_id=customer_id,
        data=update_data,
        logo=logo,
    )

@router.delete("/{customer_id}")
async def delete_customer(
        customer_id: int = Path(..., description="The customer id"),
        db: AsyncSession = Depends(get_db),
):
    return await CustomerService.delete_customer_by_id(db=db, customer_id=customer_id)

@router.post("/login")
async def login(
    request_data: LoginRequest,
    request: Request,
    db: AsyncSession = Depends(get_db),
):
    ip = request.client.host
    result = await AuthService.login(request_data, db, ip)
    return {
        "data": result,
        "status": True
    }

@router.get("/auth/google/redirect_url")
async def get_google_redirect_url(redirect_uri: str):
    return {
        "data" : generate_google_oauth_redirect_uri(redirect_uri=redirect_uri),
        "status" : True
    }
@router.get("/auth/google/send_code")
async def get_google_redirect_url(redirect_uri: str, code: str, db: AsyncSession = Depends(get_db)):
    data =  await get_customer_information_by_code(code=code, redirect_uri=redirect_uri)
    if not data:
        return {
            "data" : '',
            "status" : False,
            "error" : "Невідома помилка при авторизації через Google. Спробуте будь-ласка пізніше"
        }
    else:
        data = await CustomerService.get_or_add_customer_google(db=db, data=data)
        return {
            "data" : data,
            "status" : True
        }