from fastapi import APIRouter, HTTPException, Depends, Request, Query, Body
from sqlalchemy.orm import Session
import json

from typing import Dict
from src.database.session import get_db
from src.modules.prompt.schemas.requests import AddressData, BankStatementData, VehicleDocumentData, BusinessDocumentData, MultiDocumentVerificationRequest
from src.modules.prompt.schemas.responses import AddressMatchResponse
import src.modules.prompt.controller as prompt_controller
from src.core.logging import logger
from typing import List


router = APIRouter()

@router.post("/verify-address", response_model=AddressMatchResponse)
async def verify_address_with_document(
    file_type: str = Query(..., description="Type of document e.g. residence_documents, bank_statement"),
    file_url: str = Query(..., description="Public URL (or comma list) of the document image/PDF"),
    raw_body: dict = Body(..., description="JSON body: AddressData for residence_documents OR BankStatementData for bank_statement"),
    request: Request = None,
    db: Session = Depends(get_db)
):
    """Verify structured data against a remote document.

    file_type=bank_statement expects body:
    {
        "first_name": "MP",
        "middle_name": "",
        "last_name": "Convergent",
        "bank_name": "Bank of America",
        "account_type": "Saving",
        "balance": "10000.00"
    }

    file_type=residence_documents expects AddressData body with address fields.
    """
    try:
        if file_type == "bank_statement":
            try:
                parsed = BankStatementData(**raw_body)
            except Exception as e:
                raise HTTPException(status_code=422, detail=f"Invalid bank_statement body: {e}")
        elif file_type == "vehicle_document":
            try:
                parsed = VehicleDocumentData(**raw_body)
            except Exception as e:
                raise HTTPException(status_code=422, detail=f"Invalid vehicle_document body: {e}")
        elif file_type == "business_documents":
            try:
                parsed = BusinessDocumentData(**raw_body)
            except Exception as e:
                raise HTTPException(status_code=422, detail=f"Invalid business_documents body: {e}")
        else:
            try:
                parsed = AddressData(**raw_body)
            except Exception as e:
                raise HTTPException(status_code=422, detail=f"Invalid address body: {e}")

        return await prompt_controller.verify_address_with_document(db, file_type, file_url, parsed, request)
    except HTTPException:
        raise
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Internal server error: {str(e)}")


@router.post("/verify-documents")
async def verify_documents(
    body: dict = Body(..., description="Unified multi-document verification body"),
    request: Request = None,
    db: Session = Depends(get_db)
):
    """New unified endpoint supporting multi-file verification in JSON body.

    Accepts body matching MultiDocumentVerificationRequest. Example bank statement:
    {
        "file_type": "bank_statement",
        "file_urls": ["https://example.com/a.pdf", "https://example.com/b.pdf"],
        "data": {
            "first_name": "MP",
            "middle_name": "",
            "last_name": "Convergent",
            "bank_name": "Bank of America",
            "account_type": "Saving",
            "balance": "10000.00"
        }
    }
    Residence document:
    {
        "file_type": "residence_documents",
        "file_urls": ["https://example.com/lease_pg1.jpg"],
        "data": { ... AddressData ... }
    }
    """              
    try:
        parsed_request = MultiDocumentVerificationRequest.from_raw(body)
        logger.info(f"Request started for following payload {parsed_request}")
    except Exception as e:
        logger.error(f"Request started but got error {e}")
        raise HTTPException(status_code=422, detail=f"Invalid request body: {e}")

    return await prompt_controller.verify_multi_documents(db, parsed_request, request)

#for celery testing



@router.post("/verify-documents-celery")
def verify_documents_celery(
    body: List[dict] = Body(..., description="Unified multi-document verification body"),
    request: Request = None,
    db: Session = Depends(get_db)
): 
    """Route to submit verification tasks to Celery queue"""
    from src.utils.celery_tasks import process_verification_task
    from src.modules.models import BnkAIReqRes
    from uuid import uuid4
    from datetime import datetime
    from urllib.parse import urlparse
    
    submitted_tasks = []
    
    for item in body:
        try:
            # Validate request
            parsed_request = MultiDocumentVerificationRequest.from_raw(item)
            logger.info(f"Request validated for {len(parsed_request.file_urls)} file(s)")
            parsed = urlparse(item.get('callback_url'))
            last_param = parsed.path.rstrip("/").split("/")[-1]
            # Save request to database first
            request_id = last_param
            celery_job = BnkAIReqRes(
                request_id=last_param,
                request=item,  # Store original dict
                callback_url=item.get('callback_url'),
                created_at=datetime.utcnow()
            )
            db.add(celery_job)
            db.commit()
            db.refresh(celery_job)  # Get the auto-generated id
            
            # Dispatch Celery task with job_id (primary key)
            task = process_verification_task.delay(celery_job.id)
            
            submitted_tasks.append({
                "request_id": last_param,
                "job_id": celery_job.id,
                "task_id": task.id,
                "status": "submitted"
            })
            
        except Exception as e:
            logger.error(f"Failed to submit task: {e}")
            raise HTTPException(status_code=422, detail=f"Invalid request body: {e}")
    
    return {
        "message": f"{len(submitted_tasks)} task(s) submitted successfully",
        "tasks": submitted_tasks
    }




#TESTING CELERY WITHOUR DB STORAGE:


@router.post("/verify-documents-celery-withoutdb")
def verify_documents_celery_withoutdb(
    body: List[dict] = Body(..., description="Unified multi-document verification body (NO DB)"),
    request: Request = None
): 
    """Route to submit verification tasks to Celery queue WITHOUT database storage"""
    from src.utils.celery_tasks import process_verification_task_withoutdb
    from uuid import uuid4
    
    submitted_tasks = []
    
    for item in body:
        try:
            # Validate request
            parsed_request = MultiDocumentVerificationRequest.from_raw(item)
            logger.info(f"[NO-DB] Request validated for {len(parsed_request.file_urls)} file(s)")
            
            # Generate request_id but DON'T save to database
            request_id = str(uuid4())
            
            # Dispatch Celery task with request_id AND full request data
            task = process_verification_task_withoutdb.delay(request_id, item)
            
            submitted_tasks.append({
                "request_id": request_id,
                "task_id": task.id,
                "status": "submitted"
            })
            
        except Exception as e:
            logger.error(f"[NO-DB] Failed to submit task: {e}")
            raise HTTPException(status_code=422, detail=f"Invalid request body: {e}")
    
    return {
        "message": f"{len(submitted_tasks)} task(s) submitted successfully (NO DB)",
        "tasks": submitted_tasks
    }


# NO GET ENDPOINT FOR NO-DB FLOW - Results sent via callback only
# Frontend should rely on callback_url to receive results