import os
import time
import io
from fastapi import FastAPI, Request, File, UploadFile, Form
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from PIL import Image
from loguru import logger

from core.detector import ClothingDetector
from core.encoder import ImageEncoder
from core.matcher import MatchResult
from db.faiss_mgr import FaissManager

app = FastAPI(title="Image Identification System")

# Initialize components
templates = Jinja2Templates(directory="templates")
detector = ClothingDetector()
encoder = ImageEncoder()
faiss_mgr = FaissManager()

@app.get("/", response_class=HTMLResponse)
async def index(request: Request):
    return templates.TemplateResponse("index.html", {"request": request})

@app.post("/match")
async def match_image(
    file: UploadFile = File(...),
    score_threshold: float = Form(0.5)
):
    start_all = time.time()
    
    try:
        # 1. Read Image
        contents = await file.read()
        image = Image.open(io.BytesIO(contents)).convert("RGB")
        
        # 2. Detector: Remove noise (crop products)
        logger.info("Step 1: Detecting and cropping...")
        crops = detector.detect_and_crop(image)
        logger.info(f"Detected {len(crops)} items.")

        final_response_results = []

        # 3. Process each crop
        for i, crop in enumerate(crops):
            logger.info(f"Processing crop {i+1}...")
            
            # Encoder: Get vector
            embedding = encoder.encode_image(crop)
            
            # FAISS: Search in DB
            distances, raw_results = faiss_mgr.search(embedding, top_k=5)
            
            # Matcher: Analyze confidence
            matcher = MatchResult(raw_results)
            matcher.analyze_confidence(score_threshold=score_threshold)
            
            result_data = matcher.to_dict()
            final_response_results.append(result_data)

        total_time = time.time() - start_all
        
        return JSONResponse({
            "status": "success",
            "process_time": f"{total_time:.3f}s",
            "detections": final_response_results
        })

    except Exception as e:
        logger.error(f"Processing failed: {e}")
        return JSONResponse({"status": "error", "message": str(e)}, status_code=500)

if __name__ == "__main__":
    import uvicorn
    uvicorn.run("main:app", host="0.0.0.0", port=8010, reload=True)
