"""
AI Invoice Assistant using MiniMax M2.7.
Handles conversational invoice creation with strict safety rules.
"""

import os
import json
import re
import httpx
from dotenv import load_dotenv
from decimal import Decimal
from datetime import datetime
from typing import Optional

load_dotenv()

MINIMAX_API_URL = "https://api.minimax.chat/v1"
AI_MODEL = os.getenv("AI_MODEL", "minimax/minimax-m2.7")
AI_API_KEY = os.getenv("AI_API_KEY", "")


SYSTEM_PROMPT = """You are an AI invoice assistant for a New Zealand ERP system.
Your role is to help users create invoice drafts and query invoice/customer/product information.

You can ONLY:
- Search for customers, products, subscriptions, invoices
- Create invoice drafts (status='draft')
- Suggest follow-up actions

You MUST NEVER:
- Send emails directly
- Mark invoices as paid or void them
- Delete any data

When creating an invoice draft, return structured JSON:
{
  "action": "create_invoice_draft",
  "customer_name": "...",
  "items": [{"description": "...", "quantity": N, "unit_price": N.NN, "tax_rate": 0.15}],
  "currency": "NZD",
  "invoice_date": "YYYY-MM-DD",
  "due_date": "YYYY-MM-DD",
  "notes": "..."
}

Query format:
{
  "action": "query",
  "query_type": "customer|invoice|product|subscription|stats",
  "filters": {...}
}

Conversation style: brief, professional. Always ask user to confirm before creating anything.
"""


async def chat_with_ai(
    user_message: str,
    context: Optional[list[dict]] = None,
) -> dict:
    """Send message to MiniMax AI and return response."""
    if not AI_API_KEY:
        return {
            "role": "assistant",
            "content": "AI API key not configured. Please set AI_API_KEY in system config."
        }
    
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    
    if context:
        for msg in context[-5:]:
            messages.append({"role": msg["role"], "content": msg["content"]})
    
    messages.append({"role": "user", "content": user_message})
    
    try:
        async with httpx.AsyncClient(timeout=120) as client:
            resp = await client.post(
                f"{MINIMAX_API_URL}/text/chatcompletion_pro2",
                headers={
                    "Authorization": f"Bearer {AI_API_KEY}",
                    "Content-Type": "application/json",
                },
                json={
                    "model": AI_MODEL,
                    "messages": messages,
                    "max_tokens": 1024,
                    "temperature": 0.3,
                }
            )
            
            if resp.status_code != 200:
                return {
                    "role": "assistant",
                    "content": f"AI API error: {resp.status_code} {resp.text[:200]}"
                }
            
            data = resp.json()
            choice = data.get("choices", [{}])[0]
            content = choice.get("message", {}).get("content", "")
            
            return {
                "role": "assistant",
                "content": content,
                "usage": data.get("usage", {}),
            }
    
    except Exception as e:
        return {
            "role": "assistant",
            "content": f"AI service unavailable: {str(e)}"
        }


def parse_ai_draft(raw_text: str) -> Optional[dict]:
    """Parse AI response text to extract structured JSON if present."""
    match = re.search(r"```(?:json)?\s*(\{.*?\})\s*```", raw_text, re.DOTALL)
    if match:
        try:
            return json.loads(match.group(1))
        except json.JSONDecodeError:
            pass
    
    match = re.search(r"\{.*\}", raw_text, re.DOTALL)
    if match:
        try:
            return json.loads(match.group(0))
        except json.JSONDecodeError:
            pass
    
    return None


def validate_draft_data(draft: dict) -> tuple[bool, str]:
    """Validate draft data before creating invoice. Returns (valid, error_message)."""
    required = ["customer_name", "items"]
    for field in required:
        if field not in draft:
            return False, f"Missing required field: {field}"
    
    if not isinstance(draft["items"], list) or len(draft["items"]) == 0:
        return False, "Items list cannot be empty"
    
    for i, item in enumerate(draft["items"]):
        if "quantity" in item and float(item["quantity"]) <= 0:
            return False, f"Item {i+1}: quantity must be positive"
        if "unit_price" in item and float(item["unit_price"]) < 0:
            return False, f"Item {i+1}: unit_price cannot be negative"
    
    return True, ""