from __future__ import annotations
import uuid
from datetime import datetime
from typing import Optional
from fastapi import APIRouter, Depends, HTTPException
from sqlalchemy.orm import Session
from pydantic import BaseModel
from app.database import get_db
from app.models.customer import Customer
from app.services.auth import get_current_user

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


class CustomerCreate(BaseModel):
    name: str
    customer_type: str = "Retail"
    phone: Optional[str] = None
    email: Optional[str] = None
    address: Optional[str] = None
    city: Optional[str] = None
    gst_number: Optional[str] = None
    total_purchases: float = 0.0
    outstanding: float = 0.0
    loyalty_points: int = 0
    is_active: bool = True

class CustomerUpdate(BaseModel):
    name: Optional[str] = None
    customer_type: Optional[str] = None
    phone: Optional[str] = None
    email: Optional[str] = None
    address: Optional[str] = None
    city: Optional[str] = None
    gst_number: Optional[str] = None
    total_purchases: Optional[float] = None
    outstanding: Optional[float] = None
    loyalty_points: Optional[int] = None
    is_active: Optional[bool] = None

class CustomerOut(BaseModel):
    id: str
    code: str
    name: str
    customer_type: str
    phone: Optional[str] = None
    email: Optional[str] = None
    address: Optional[str] = None
    city: Optional[str] = None
    gst_number: Optional[str] = None
    total_purchases: float
    outstanding: float
    loyalty_points: int
    is_active: bool
    created_at: datetime
    updated_at: datetime
    model_config = {"from_attributes": True}


def _generate_customer_code(db: Session) -> str:
    year = datetime.now().year
    last = db.query(Customer).filter(
        Customer.code.like(f"CUS-{year}-%")
    ).order_by(Customer.code.desc()).first()
    if last:
        seq = int(last.code.split("-")[-1]) + 1
    else:
        seq = 1
    return f"CUS-{year}-{seq:06d}"


@router.get("", response_model=list[CustomerOut])
def list_customers(
    search: Optional[str] = None,
    customer_type: Optional[str] = None,
    is_active: Optional[bool] = None,
    db: Session = Depends(get_db),
    _=Depends(get_current_user),
):
    q = db.query(Customer)
    if search:
        q = q.filter(Customer.name.ilike(f"%{search}%"))
    if customer_type:
        q = q.filter(Customer.customer_type == customer_type)
    if is_active is not None:
        q = q.filter(Customer.is_active == is_active)
    return q.order_by(Customer.name).all()


@router.post("", response_model=CustomerOut, status_code=201)
def create_customer(data: CustomerCreate, db: Session = Depends(get_db), _=Depends(get_current_user)):
    obj = Customer(**data.model_dump(), code=_generate_customer_code(db))
    db.add(obj)
    db.commit()
    db.refresh(obj)
    return obj


@router.get("/{customer_id}", response_model=CustomerOut)
def get_customer(customer_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    obj = db.query(Customer).filter(Customer.id == customer_id).first()
    if not obj:
        raise HTTPException(status_code=404, detail="Customer not found")
    return obj


@router.put("/{customer_id}", response_model=CustomerOut)
def update_customer(customer_id: str, data: CustomerUpdate, db: Session = Depends(get_db), _=Depends(get_current_user)):
    obj = db.query(Customer).filter(Customer.id == customer_id).first()
    if not obj:
        raise HTTPException(status_code=404, detail="Customer not found")
    for k, v in data.model_dump(exclude_unset=True).items():
        setattr(obj, k, v)
    db.commit()
    db.refresh(obj)
    return obj


@router.delete("/{customer_id}")
def delete_customer(customer_id: str, db: Session = Depends(get_db), _=Depends(get_current_user)):
    obj = db.query(Customer).filter(Customer.id == customer_id).first()
    if not obj:
        raise HTTPException(status_code=404, detail="Customer not found")
    db.delete(obj)
    db.commit()
    return {"detail": "Customer deleted"}
