# controller.py
from fastapi import HTTPException
from .service import QdrantService
from .schema import  SearchRequest,SearchResponse,SearchResult
from sqlalchemy.orm import Session
from src.menu_design.apps.editor.models import Templates
import json

qdrant = QdrantService()



##-----------------------Doccument inser from the Template table ---------------------------------------

# 


def insert_documents_handler(db: Session):
    try:
        # Fetch unprocessed templates with all needed fields
        templates_to_process = db.query(
            Templates.template_id,
            Templates.template_name,
            Templates.template_url,
            Templates.template_metadata,
            
        ).filter(
            Templates.data_process == 0
        ).all()

        if not templates_to_process:
            raise HTTPException(404, "No unprocessed templates found")

        collection_map = {}
        failed_templates = []
        
        for template in templates_to_process:
            try:
                document = {
                    "id": str(template.template_id),
                    "template_url": template.template_url,
                    "template_name": template.template_name,
                    "template_metadata": json.loads(template.template_metadata) 
                                       if template.template_metadata 
                                       else {}
                }

                collection_name = template.template_name
                if collection_name not in collection_map:
                    collection_map[collection_name] = []
                collection_map[collection_name].append(document)

            except Exception as e:
                print(f"Error processing template ID {template.template_id}: {e}")
                failed_templates.append({
                    "template_id": template.template_id,
                    "error": str(e)
                })
                continue

        if not collection_map:
            raise HTTPException(400, "No valid templates found to process")

        # Insert documents into Qdrant
        results = {}
        for collection_name, docs in collection_map.items():
            collection_name = "design_template"
            print("Docs",docs)

            try:
                result = qdrant.insert_documents(docs, collection_name, db=db)
                results[collection_name] = result
            except Exception as e:
                print(f"Error inserting to collection {collection_name}: {e}")
                results[collection_name] = {"success": False, "error": str(e)}

        # Mark processed templates
        processed_ids = [t.template_id for t in templates_to_process]
        db.query(Templates).filter(Templates.template_id.in_(processed_ids)).update(
            {"data_process": 1}, synchronize_session=False
        )
        db.commit()

        return {
            "success": True,
            "message": f"Processed {len(templates_to_process)} templates",
            "results": results,
            "failed_count": len(failed_templates),
            "collections_updated": list(collection_map.keys())
        }

    except Exception as e:
        db.rollback()
        raise HTTPException(500, f"Insert failed: {str(e)}")



def search_handler(request: SearchRequest):
    try:
        # Debug logging
        print(f"\n=== SEARCH DEBUG START ===")
        print(f"Query: '{request.query}'")
        print(f"Collection: {request.collection_name}")
        
        # Check collection exists
        if not qdrant.client.collection_exists(request.collection_name):
            available = [c.name for c in qdrant.client.get_collections().collections]
            raise HTTPException(404, f"Collection not found. Available: {available}")
        
        # Generate embedding
        query_embedding = qdrant._get_embedding(request.query)
        
        # Check if embedding is valid
        if all(v == 0.0 for v in query_embedding):
            return SearchResponse(
                query=request.query,
                results=[],
                total_results=0
            )
        
        # Execute search with threshold
        results = qdrant.client.search(
            collection_name=request.collection_name,
            query_vector=query_embedding,
            limit=request.limit,
            score_threshold=request.score_threshold,
            with_payload=True
        )
        
        # Format results with the specific fields we want
        formatted_results = []
        for r in results:
            # if r.score>0.6:
            formatted_results.append(SearchResult(
                id=str(r.id),
                score=r.score,
                template_url=r.payload.get("template_url", ""),
                template_id=r.payload.get("template_id", ""),
                template_name=r.payload.get("template_name", ""),
                template_metadata=r.payload.get("template_metadata", {}),
                searchable_text=r.payload.get("searchable_text", ""),
                highlights=qdrant._find_highlights(request.query, r.payload)
            ))
        
        print(f"=== SEARCH DEBUG END ===\n")
        
        return SearchResponse(
            query=request.query,
            results=formatted_results,
            total_results=len(formatted_results)
        )
        
    except HTTPException:
        raise
    except Exception as e:
        print(f"Search error: {str(e)}")
        raise HTTPException(500, detail=str(e))


def format_results(results):
    """Fixed format_results function"""
    formatted = []
    for hit in results:
        print(f"Formatting result - ID: {hit.id}, Score: {hit.score}")
        
        formatted.append({
            "id": hit.payload.get("original_id", hit.id),  # Use original_id from payload
            "score": hit.score,
            "data": hit.payload.get("json_data", {}),
            "metadata": hit.payload.get("metadata", {}),
            "searchable_text": hit.payload.get("searchable_text", "")
        })
    return formatted

def list_collections_handler():
    return qdrant.list_collections()

def collection_info_handler(name: str):
    return qdrant.collection_info(name)

def delete_collection_handler(name: str):
    return qdrant.delete_collection(name)

def count_points_handler(name: str):
    return {"count": qdrant.count_points(name)}

def health_handler():
    try:
        return {
            "status": "healthy",
            "collections": qdrant.list_collections()
        }
    except:
        return {"status": "unhealthy"}
