"""
ai/claude_processor.py — Send raw bank/CSV rows to Claude, get structured
Tally accounting entries back (Dr/Cr, ledger heads, UAE VAT).
"""
import json
import re

import anthropic

from config import ANTHROPIC_API_KEY, CLAUDE_MODEL, MAX_TOKENS
from ai.prompts import ACCOUNTING_SYSTEM_PROMPT

client = anthropic.Anthropic(api_key=ANTHROPIC_API_KEY)


def _extract_json(text: str):
    """Be forgiving: pull the first JSON array out of the model's reply."""
    text = text.strip()
    # Strip ```json ... ``` fences if present
    text = re.sub(r"^```(?:json)?\s*|\s*```$", "", text, flags=re.MULTILINE).strip()
    try:
        return json.loads(text)
    except json.JSONDecodeError:
        match = re.search(r"\[.*\]", text, re.DOTALL)
        if match:
            return json.loads(match.group(0))
        raise


def classify_transactions(raw_data: list) -> list:
    """
    Send raw bank/CSV rows to Claude. Returns structured accounting entries.

    Input:  [{"date": "2025-06-01", "description": "ADCB ATM", "amount": -500}]
    Output: [{"date":..., "voucher_type":..., "debit_ledger":...,
              "credit_ledger":..., "amount":..., "narration":..., "vat_amount":...}]
    """
    user_message = f"""
Here are the raw transactions to classify and convert to Tally entries.
Return ONLY a JSON array. No explanation.

Transactions:
{json.dumps(raw_data, indent=2)}
"""

    response = client.messages.create(
        model=CLAUDE_MODEL,
        max_tokens=MAX_TOKENS,
        system=ACCOUNTING_SYSTEM_PROMPT,
        messages=[{"role": "user", "content": user_message}],
    )

    text = response.content[0].text
    return _extract_json(text)


def generate_narration(entry: dict) -> str:
    """Ask Claude to write a professional Tally narration for one entry."""
    response = client.messages.create(
        model=CLAUDE_MODEL,
        max_tokens=100,
        messages=[{
            "role": "user",
            "content": f"Write a 1-line professional Tally narration for: {entry}",
        }],
    )
    return response.content[0].text.strip()
