from fastapi import APIRouter, Depends
from pydantic import BaseModel
from sqlalchemy.orm import Session
from typing import Optional
from app.core.database import get_db
from app.core.models import Customer, Invoice, InvoiceItem, InvoiceStatus, InvoiceEvent
from app.services.ai_service import chat_with_ai, parse_ai_draft, validate_draft_data
from app.services.invoice_service import generate_invoice_number, calculate_item
from app.api.auth import get_current_user
from datetime import datetime
import json

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


class ChatRequest(BaseModel):
    message: str
    thread_id: Optional[str] = None


class ChatResponse(BaseModel):
    reply: str
    action: Optional[str] = None
    draft_id: Optional[int] = None


@router.post("/chat", response_model=ChatResponse)
async def chat(
    req: ChatRequest,
    db: Session = Depends(get_db),
    current_user = Depends(get_current_user),
):
    """Chat with the AI assistant."""
    response = await chat_with_ai(req.message, context=None)
    reply = response.get("content", "Sorry, AI is currently unavailable.")
    
    draft_data = parse_ai_draft(reply)
    draft_id = None
    action = None
    
    if draft_data and draft_data.get("action") == "create_invoice_draft":
        valid, error = validate_draft_data(draft_data)
        if valid:
            customer_name = draft_data["customer_name"]
            customer = db.query(Customer).filter(Customer.name.ilike(f"%{customer_name}%")).first()
            if not customer:
                return ChatResponse(
                    reply=f"Customer '{customer_name}' not found. Please check the name.",
                    action="query"
                )
            
            invoice = Invoice(
                invoice_number=generate_invoice_number(db),
                customer_id=customer.id,
                invoice_date=draft_data.get("invoice_date", datetime.now().date()),
                due_date=draft_data.get("due_date"),
                currency=draft_data.get("currency", "NZD"),
                notes=draft_data.get("notes", ""),
                status=InvoiceStatus.draft,
            )
            db.add(invoice)
            db.flush()
            
            for item_data in draft_data["items"]:
                qty = float(item_data.get("quantity", 1))
                price = float(item_data.get("unit_price", 0))
                rate = float(item_data.get("tax_rate", 0.15))
                calculated = calculate_item({"quantity": qty, "unit_price": price, "tax_rate": rate})
                
                item = InvoiceItem(
                    invoice_id=invoice.id,
                    description=item_data.get("description", "Item"),
                    quantity=qty,
                    unit_price=price,
                    tax_rate=rate,
                    subtotal=calculated["subtotal"],
                    tax_amount=calculated["tax_amount"],
                    total=calculated["total"],
                )
                db.add(item)
            
            items = db.query(InvoiceItem).filter(InvoiceItem.invoice_id == invoice.id).all()
            invoice.subtotal = sum(i.subtotal for i in items)
            invoice.total_tax = sum(i.tax_amount for i in items)
            invoice.total_amount = sum(i.total for i in items)
            
            db.commit()
            
            event = InvoiceEvent(
                invoice_id=invoice.id,
                event_type="ai_drafted",
                actor_type="ai",
                actor_name="AI Assistant",
                message="AI draft created from chat",
                metadata_json=json.dumps({"raw": draft_data}),
            )
            db.add(event)
            db.commit()
            
            draft_id = invoice.id
            action = "create_draft"
            reply = f"✅ Invoice draft created: {invoice.invoice_number}\n\nReview it in the Invoices page and click 'Issue' when ready."
        else:
            reply = f"AI draft validation error: {error}"
            action = "error"
    
    return ChatResponse(reply=reply, action=action, draft_id=draft_id)