import uuid
import json
import csv
import io

from fastapi import APIRouter, Depends, UploadFile, File, HTTPException, status
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession

from app.auth.api_key import get_user_by_api_key
from app.auth.deps import get_current_user
from app.database import get_db
from app.models.collection import Collection
from app.models.schemas import TicketInput, TicketsUpload, TicketsUploadResponse
from app.models.user import User
from app.services.chunking import build_chunk
from app.services.embedding import embed_texts
from app.services.vector_store import upsert_chunks, get_existing_ticket_ids

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


async def process_tickets(
    db: AsyncSession,
    collection_id: uuid.UUID,
    user: User,
    tickets: list[TicketInput],
) -> TicketsUploadResponse:
    result = await db.execute(
        select(Collection).where(Collection.id == collection_id, Collection.user_id == user.id)
    )
    collection = result.scalar_one_or_none()
    if not collection:
        raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Collection not found")

    existing_ids = get_existing_ticket_ids(str(user.id), str(collection_id))

    processed = 0
    skipped = 0
    chunks = []

    for t in tickets:
        if t.ticket_id in existing_ids:
            skipped += 1
            continue
        ticket_dict = {
            "ticket_id": t.ticket_id,
            "category": t.category,
            "description": t.description,
            "client": t.client,
            "messages": [{"role": m.role, "text": m.text} for m in t.messages],
        }
        chunk = build_chunk(ticket_dict)
        if chunk:
            chunk["tenant_id"] = str(user.id)
            chunk["collection_id"] = str(collection_id)
            chunks.append(chunk)
            processed += 1
        else:
            skipped += 1

    if chunks:
        search_texts = [c["search_text"] for c in chunks]
        vectors = await embed_texts(search_texts)
        await upsert_chunks(str(user.id), chunks, vectors)

        collection.ticket_count += processed
        await db.commit()

    return TicketsUploadResponse(
        processed=processed,
        skipped=skipped,
        collection_ticket_count=collection.ticket_count,
    )


@router.post("/{collection_id}/tickets", response_model=TicketsUploadResponse)
async def upload_tickets_json(
    collection_id: uuid.UUID,
    body: TicketsUpload,
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    return await process_tickets(db, collection_id, user, body.tickets)


@router.post("/{collection_id}/tickets/upload", response_model=TicketsUploadResponse)
async def upload_tickets_file(
    collection_id: uuid.UUID,
    file: UploadFile = File(...),
    user: User = Depends(get_current_user),
    db: AsyncSession = Depends(get_db),
):
    content = await file.read()

    if file.filename.endswith(".json"):
        data = json.loads(content)
        tickets = [TicketInput(**t) for t in data] if isinstance(data, list) else [TicketInput(**data)]
    elif file.filename.endswith(".csv"):
        text = content.decode("utf-8-sig")
        reader = csv.DictReader(io.StringIO(text))
        tickets = []
        for row in reader:
            tickets.append(
                TicketInput(
                    ticket_id=row.get("ticket_id", ""),
                    category=row.get("category", ""),
                    description=row.get("description", ""),
                    client=row.get("client", ""),
                )
            )
    else:
        raise HTTPException(
            status_code=status.HTTP_400_BAD_REQUEST,
            detail="Unsupported format. Use JSON or CSV.",
        )

    return await process_tickets(db, collection_id, user, tickets)
