"""
ABOS AI Worker – Meeting Analyser Router
========================================
Extracts action items, generates tasks, aligns them with projects, and supports
Human-In-Loop chat verification. Connected to React and Spring Boot.
"""

from __future__ import annotations

import json
import logging
import re
from typing import Any, Dict

import httpx
from fastapi import APIRouter, HTTPException, status

from app.config import settings
from app.schemas import (
    MeetingAnalyzeRequest,
    MeetingAnalyzeResult,
    MeetingAskRequest,
    MeetingAskResponse,
)

logger = logging.getLogger(__name__)

meeting_router = APIRouter()

# Simple transient store for meeting analysis (UUID/MeetingID -> Result)
meeting_transient_store: Dict[str, MeetingAnalyzeResult] = {}

# ---------------------------------------------------------------------------
# Helper function: Fetch Projects & credentials from Spring Boot
# ---------------------------------------------------------------------------
async def fetch_projects_and_keys(tenant_id: str, auth_token: str) -> Dict[str, Any]:
    """
    Fetches the list of active projects and AI API keys from the Spring Boot ERP database.
    """
    spring_boot_base = "http://localhost:8080"
    url = f"{spring_boot_base}/api/finance/meetings/config"
    headers = {
        "Authorization": f"Bearer {auth_token}",
        "X-Tenant-ID": tenant_id,
        "Content-Type": "application/json"
    }

    try:
        async with httpx.AsyncClient(timeout=10) as client:
            res = await client.get(url, headers=headers)
            if res.status_code == 200:
                return res.json()
    except Exception as exc:
        logger.warning("Could not fetch meeting config from Spring Boot: %s. Using mocks.", exc)

    # Fallback mockup config
    return {
        "openai_api_key": "mock-openai-key",
        "google_api_key": "mock-google-key",
        "active_projects": ["Database Migration", "ERP Module Development", "HR System Integration", "Financial Auditing"]
    }

# ---------------------------------------------------------------------------
# POST /meeting/analyze
# ---------------------------------------------------------------------------
@meeting_router.post(
    "/meeting/analyze",
    response_model=MeetingAnalyzeResult,
    status_code=status.HTTP_200_OK,
    summary="Analyze meeting transcription into action items and projects",
    tags=["Meeting-Analyzer"],
)
async def analyze_meeting(request: MeetingAnalyzeRequest) -> MeetingAnalyzeResult:
    """
    Takes transcription text, extracts action items (person, summary, block),
    generates tasks, and aligns them with active projects.
    """
    # 1. Fetch credentials and active projects from Spring Boot
    config = await fetch_projects_and_keys(
        tenant_id=request.tenant_id,
        auth_token=request.spring_boot_auth_token
    )

    openai_key = config.get("openai_api_key", "")
    google_key = config.get("google_api_key", "")
    active_projects = config.get("active_projects", [])

    # Resolve LLM Key (favoring OpenAI first, then Google/OpenRouter fallback)
    llm_key = openai_key if openai_key != "mock-openai-key" else google_key

    # 2. Build prompt
    prompt = (
        "You are an advanced Meeting Assistant. Process this transcription text in two steps:\n"
        "Step 1: Extract all actionable points. For each, note who said it or who is responsible (personSpeaker), "
        "a brief summary, and the exact discussion quote (actualBlockOfDiscussion).\n"
        "Step 2: Generate formal tasks matching these action items. Match each task to one of these projects: "
        f"{', '.join(active_projects)}. If none fit, use null.\n\n"
        "Respond ONLY with a valid JSON object matching this structure:\n"
        "{\n"
        "  \"meetingId\": \"meeting-id-here\",\n"
        "  \"title\": \"Identified meeting title\",\n"
        "  \"summary\": \"Brief overview of discussed topics\",\n"
        "  \"actionItems\": [\n"
        "    {\n"
        "      \"personSpeaker\": \"John\",\n"
        "      \"summary\": \"Update database schemas\",\n"
        "      \"actualBlockOfDiscussion\": \"John said: 'I will write the SQL scripts tomorrow'\"\n"
        "    }\n"
        "  ],\n"
        "  \"generatedTasks\": [\n"
        "    {\n"
        "      \"title\": \"Update database schemas\",\n"
        "      \"description\": \"Write and run migration scripts\",\n"
        "      \"assignee\": \"John\",\n"
        "      \"priority\": \"HIGH\",\n"
        "      \"dueDateRecommendation\": \"YYYY-MM-DD\",\n"
        "      \"projectNameRef\": \"Database Migration\"\n"
        "    }\n"
        "  ]\n"
        "}"
    )

    system_message = "You are a precise JSON extractor. Respond with raw JSON only."
    user_message = f"{prompt}\n\n--- TRANSCRIPT START ---\n{request.transcript}\n--- TRANSCRIPT END ---"

    # Dummy fallback response if LLM keys are absent
    if not llm_key or "mock-" in llm_key:
        logger.info("Using mock meeting analysis (no credentials supplied)")
        mock_result = MeetingAnalyzeResult(
            meetingId=request.meeting_id,
            title=request.title or "Weekly ERP Sync",
            summary="Discussion regarding database schema updates and module development.",
            actionItems=[
                {
                    "personSpeaker": "Sarah",
                    "summary": "Review database migration scripts",
                    "actualBlockOfDiscussion": "Sarah: 'I will take a look at the SQL migration script by Thursday.'"
                }
            ],
            generatedTasks=[
                {
                    "title": "Review database migration scripts",
                    "description": "Verify SQL queries and index creations",
                    "assignee": "Sarah",
                    "priority": "HIGH",
                    "dueDateRecommendation": "2026-06-28",
                    "projectNameRef": "Database Migration"
                }
            ]
        )
        meeting_transient_store[request.meeting_id] = mock_result
        return mock_result

    # 3. Call LLM (using OpenRouter endpoint with dynamic key)
    payload = {
        "model": "google/gemini-2.0-flash-exp:free",
        "messages": [
            {"role": "system", "content": system_message},
            {"role": "user", "content": user_message}
        ],
        "temperature": 0.2,
        "response_format": {"type": "json_object"}
    }

    try:
        headers = {
            "Authorization": f"Bearer {llm_key}",
            "Content-Type": "application/json"
        }
        async with httpx.AsyncClient(timeout=60) as client:
            res = await client.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
            if res.status_code == 200:
                content = res.json()["choices"][0]["message"]["content"]
                # Clean markdown fences
                match = re.search(r"```(?:json)?\s*([\s\S]*?)\s*```", content, re.IGNORECASE)
                cleaned = match.group(1).strip() if match else content.strip()
                
                parsed_data = json.loads(cleaned)
                parsed_data["meetingId"] = request.meeting_id
                
                result = MeetingAnalyzeResult.model_validate(parsed_data)
                meeting_transient_store[request.meeting_id] = result
                return result
    except Exception as exc:
        logger.error("Failed to analyze transcript via LLM: %s", exc)

    raise HTTPException(
        status_code=status.HTTP_502_BAD_GATEWAY,
        detail="Meeting analysis failed due to LLM provider issues."
    )

# ---------------------------------------------------------------------------
# POST /meeting/ask
# ---------------------------------------------------------------------------
@meeting_router.post(
    "/meeting/ask",
    response_model=MeetingAskResponse,
    status_code=status.HTTP_200_OK,
    summary="Ask questions about the transcription (HITL feature)",
    tags=["Meeting-Analyzer"],
)
async def ask_about_meeting(request: MeetingAskRequest) -> MeetingAskResponse:
    """
    Processes a direct user question regarding the meeting content/transcript.
    """
    config = await fetch_projects_and_keys(
        tenant_id=request.tenant_id,
        auth_token=request.spring_boot_auth_token
    )
    llm_key = config.get("openai_api_key", "")
    if "mock-" in llm_key or not llm_key:
        # Fallback response
        return MeetingAskResponse(
            meetingId=request.meeting_id,
            question=request.question,
            answer="This is a mock answer. Sarah mentioned she would review the database scripts by Thursday."
        )

    prompt = (
        f"Answer this user question referencing the meeting transcript below.\n"
        f"Question: {request.question}\n\n"
        f"--- TRANSCRIPT START ---\n{request.transcript}\n--- TRANSCRIPT END ---\n"
        f"Answer:"
    )

    payload = {
        "model": "google/gemini-2.0-flash-exp:free",
        "messages": [{"role": "user", "content": prompt}],
        "temperature": 0.5
    }

    try:
        headers = {
            "Authorization": f"Bearer {llm_key}",
            "Content-Type": "application/json"
        }
        async with httpx.AsyncClient(timeout=30) as client:
            res = await client.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload)
            if res.status_code == 200:
                answer = res.json()["choices"][0]["message"]["content"].strip()
                return MeetingAskResponse(
                    meetingId=request.meeting_id,
                    question=request.question,
                    answer=answer
                )
    except Exception as exc:
        logger.error("Chat question failed: %s", exc)

    raise HTTPException(
        status_code=status.HTTP_502_BAD_GATEWAY,
        detail="Meeting query failed."
    )

# ---------------------------------------------------------------------------
# POST /meeting/verify
# ---------------------------------------------------------------------------
@meeting_router.post(
    "/meeting/verify",
    status_code=status.HTTP_200_OK,
    summary="Submit human-verified meeting items and save to Spring Boot",
    tags=["Meeting-Analyzer"],
)
async def verify_meeting_items(
    body: MeetingAnalyzeResult,
    spring_boot_url: str,
    auth_token: str,
    tenant_id: str
) -> Dict[str, str]:
    """
    Submits verified Tasks and Action Items to Spring Boot to create Projects/Tasks.
    """
    headers = {
        "Authorization": f"Bearer {auth_token}",
        "X-Tenant-ID": tenant_id,
        "Content-Type": "application/json"
    }

    # Post finalized JSON data back to Core Spring Boot ERP
    payload = body.model_dump(by_alias=True, mode="json")
    
    try:
        async with httpx.AsyncClient(timeout=20) as client:
            response = await client.post(
                f"{spring_boot_url}/api/finance/meetings/finalize",
                headers=headers,
                json=payload
            )
            response.raise_for_status()
    except Exception as exc:
        logger.error("Finalizing tasks in Spring Boot failed: %s", exc)
        raise HTTPException(
            status_code=status.HTTP_502_BAD_GATEWAY,
            detail=f"Failed to save verified tasks to Spring Boot: {exc}"
        )

    # Evict transient record
    meeting_transient_store.pop(body.meeting_id, None)

    return {"status": "SUCCESS", "message": "Meeting items finalized and tasks loaded into projects."}
