"""
ACRS (Automated Complaint Resolution System) dispatch logic.

Classifies conversations via LLM and POSTs to ACRS API.
Extracted from PipelineSession for maintainability.

All functions take `p` (pipeline session instance) as first argument
to access session state (conversation_log, acrs config, llm, etc.).
"""

import json
from datetime import datetime

import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)


def dispatch_to_acrs(p):
    """Classify conversation via LLM and POST to ACRS API. Returns result dict.

    Args:
        p: PipelineSession instance.
    """
    if not p.conversation_log:
        return {'success': False, 'message': 'No conversation to dispatch'}

    # Step 1: Format conversation text
    conversation_text = "\n".join(
        f"[{m['timestamp']}] {m['speaker']}: {m['text']}"
        for m in p.conversation_log
    )

    # Step 2: Build dynamic classification prompt from dashboard config
    dept_desc = ""
    for d in p.acrs_departments:
        cats = ", ".join(f"ID {c['id']}: {c['name']}" for c in d.get('categories', []))
        dept_desc += f"  - Department ID {d['id']}: {d['name']}"
        if cats:
            dept_desc += f" (Categories: {cats})"
        dept_desc += "\n"

    type_desc = "\n".join(f"  - Type ID {t['id']}: {t['name']}" for t in p.acrs_types)
    subcat_desc = "\n".join(f"  - Subcategory ID {s['id']}: {s['name']}" for s in p.acrs_subcategories)
    rating_desc = "\n".join(f"  - Rating ID {r['id']}: {r['name']}" for r in p.acrs_ratings)

    prompt = f"""Analyze this customer service conversation and classify it.

Your response MUST be a valid JSON object with these fields:
{{
  "departmentId": <integer>,
  "typeId": <integer>,
  "categoryId": <integer>,
  "subCategoryId": <integer>,
  "ratingId": <integer>,
  "summary": "<1-2 sentence summary>",
  "emailSubject": "<short subject/topic>"
}}

AVAILABLE OPTIONS:

Departments and their categories:
{dept_desc if dept_desc else "  (none configured)"}

Types:
{type_desc if type_desc else "  (none configured)"}

Subcategories:
{subcat_desc if subcat_desc else "  (none configured)"}

Ratings:
{rating_desc if rating_desc else "  (none configured)"}

RULES:
- You MUST pick IDs from the options above. Do not invent new IDs.
- If no clear match, pick the closest available option.
- "summary" should be a concise 1-2 sentence description of the conversation.
- "emailSubject" should be a short topic/subject (max 100 chars).
- Response must be valid JSON only, no additional text.

Conversation to analyze:
\"\"\"{conversation_text}\"\"\""""

    # Step 3: Call LLM for classification
    print(f'[ACRS] Classifying conversation ({len(p.conversation_log)} messages)...')
    try:
        response = p.llm.chat.completions.create(
            model=p.llm_model,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.1
        )
        raw = response.choices[0].message.content.strip()
        if raw.startswith("```json"):
            raw = raw.replace("```json", "").replace("```", "").strip()
        elif raw.startswith("```"):
            raw = raw.replace("```", "").strip()
        classification = json.loads(raw)
        print(f'[ACRS] Classification: {json.dumps(classification, indent=2)}')
    except Exception as e:
        print(f'[ACRS] Classification error: {e}')
        return {'success': False, 'message': f'Classification failed: {e}'}

    # Step 4: Build payload
    payload = {
        "spAccount": p.acrs_sp_account or "admin",
        "incidentDate": datetime.now().strftime('%Y-%m-%d'),
        "departmentId": classification.get('departmentId'),
        "typeId": classification.get('typeId'),
        "categoryId": classification.get('categoryId'),
        "subCategoryId": classification.get('subCategoryId'),
        "name": p.session_profile or "Unknown",
        "originalEmailContent": conversation_text,
        "noc": classification.get('summary', ''),
        "emailSubject": classification.get('emailSubject', ''),
        "ratingId": classification.get('ratingId'),
    }
    # Merge any custom fields from dashboard
    for k, v in p.acrs_custom_fields.items():
        if k not in payload:
            payload[k] = v

    print(f'[ACRS] Payload: {json.dumps(payload, indent=2)}')

    # Step 5: POST to ACRS API
    headers = {
        "X-API-KEY": p.acrs_api_key,
        "Content-Type": "application/json",
        "Accept": "application/json",
    }
    try:
        resp = requests.post(
            p.acrs_api_url, json=payload,
            headers=headers, timeout=10, verify=False
        )
        print(f'[ACRS] Response: {resp.status_code}')
        if resp.status_code in (200, 201):
            resp_data = {}
            try:
                resp_data = resp.json()
            except Exception:
                pass
            case_no = resp_data.get('caseNo', resp_data.get('id', ''))
            print(f'[ACRS] Dispatch successful. Case: {case_no}')
            return {'success': True, 'message': 'Dispatch successful', 'case_no': str(case_no)}
        else:
            body = resp.text[:200]
            print(f'[ACRS] Dispatch failed ({resp.status_code}): {body}')
            return {'success': False, 'message': f'API returned {resp.status_code}'}
    except Exception as e:
        print(f'[ACRS] Request error: {e}')
        return {'success': False, 'message': f'Request failed: {e}'}


def dispatch_callback_to_acrs(p, customer_name, customer_phone, reason):
    """POST callback request to ACRS API.

    Department/type/rating from defaults, category/subcategory from LLM.

    Args:
        p: PipelineSession instance.
        customer_name: Customer's name.
        customer_phone: Customer's phone number.
        reason: Reason for the callback.
    """
    conversation_text = "\n".join(
        f"[{m['timestamp']}] {m['speaker']}: {m['text']}"
        for m in p.conversation_log
    ) if p.conversation_log else ""

    # LLM classify category + subcategory from conversation
    category_id = None
    subcategory_id = None

    # Build available options for the selected department's categories
    dept_cats = []
    for d in p.acrs_departments:
        if d.get('id') == p.acrs_callback_dept_id:
            dept_cats = d.get('categories', [])
            break
    cat_desc = "\n".join(f"  - Category ID {c['id']}: {c['name']}" for c in dept_cats)
    subcat_desc = "\n".join(f"  - Subcategory ID {s['id']}: {s['name']}" for s in p.acrs_subcategories)

    if (dept_cats or p.acrs_subcategories) and (conversation_text or reason):
        prompt = f"""Classify this callback request into a category and subcategory.

Your response MUST be a valid JSON object:
{{"categoryId": <integer or null>, "subCategoryId": <integer or null>}}

AVAILABLE OPTIONS:

Categories:
{cat_desc if cat_desc else "  (none configured)"}

Subcategories:
{subcat_desc if subcat_desc else "  (none configured)"}

RULES:
- Pick IDs from the options above only. Do not invent new IDs.
- If no clear match, pick the closest available option.
- Response must be valid JSON only, no additional text.

Callback reason: {reason}

Conversation:
\"\"\"{conversation_text}\"\"\""""

        print(f'[ACRS Callback] Classifying category/subcategory...')
        try:
            response = p.llm.chat.completions.create(
                model=p.llm_model,
                messages=[{"role": "user", "content": prompt}],
                temperature=0.1
            )
            raw = response.choices[0].message.content.strip()
            if raw.startswith("```json"):
                raw = raw.replace("```json", "").replace("```", "").strip()
            elif raw.startswith("```"):
                raw = raw.replace("```", "").strip()
            classification = json.loads(raw)
            category_id = classification.get('categoryId')
            subcategory_id = classification.get('subCategoryId')
            print(f'[ACRS Callback] Classification: categoryId={category_id}, subCategoryId={subcategory_id}')
        except Exception as e:
            print(f'[ACRS Callback] Classification error (proceeding without): {e}')

    payload = {
        "spAccount": p.acrs_sp_account or "admin",
        "incidentDate": datetime.now().strftime('%Y-%m-%d'),
        "departmentId": p.acrs_callback_dept_id,
        "typeId": p.acrs_callback_type_id,
        "categoryId": category_id,
        "subCategoryId": subcategory_id,
        "ratingId": p.acrs_callback_rating_id,
        "name": customer_name or p.session_profile or "Unknown",
        "originalEmailContent": conversation_text,
        "noc": f"Callback: {customer_name} ({customer_phone}). Reason: {reason}",
        "emailSubject": f"Callback Request: {reason[:80]}",
    }
    # Merge custom fields
    for k, v in p.acrs_custom_fields.items():
        if k not in payload:
            payload[k] = v

    print(f'[ACRS Callback] Payload: {json.dumps(payload, indent=2)}')

    headers = {
        "X-API-KEY": p.acrs_api_key,
        "Content-Type": "application/json",
        "Accept": "application/json",
    }
    try:
        resp = requests.post(
            p.acrs_api_url, json=payload,
            headers=headers, timeout=10, verify=False
        )
        print(f'[ACRS Callback] Response: {resp.status_code}')
        if resp.status_code in (200, 201):
            resp_data = {}
            try:
                resp_data = resp.json()
            except Exception:
                pass
            case_no = resp_data.get('caseNo', resp_data.get('id', ''))
            print(f'[ACRS Callback] Dispatch successful. Case: {case_no}')
            return {'success': True, 'message': 'Callback dispatch successful', 'case_no': str(case_no)}
        else:
            body = resp.text[:200]
            print(f'[ACRS Callback] Dispatch failed ({resp.status_code}): {body}')
            return {'success': False, 'message': f'API returned {resp.status_code}'}
    except Exception as e:
        print(f'[ACRS Callback] Request error: {e}')
        return {'success': False, 'message': f'Request failed: {e}'}
