/**
 * AI tax evaluation pipeline — expenses-module.
 * Calls Claude Haiku via callAI (use case: expense_tax_eval) to evaluate
 * Israeli tax deductibility using the 3-step algorithm from the spec.
 */
import type { Expense } from '@zync/types'
import type { ExpenseCategoryId } from '@zync/types'
import { callAI } from '@zync/ai'
import type { AICtx } from '@zync/ai'
import { TAX_EVAL_SYSTEM_PROMPT, buildTaxEvalUserPrompt } from './prompts'
import { ExpenseProcessingError } from './errors'

const VALID_DEDUCTION_PCTS = [0, 25, 45, 66, 100] as const
type ValidDeductionPct = (typeof VALID_DEDUCTION_PCTS)[number]

export interface TaxEvalResult {
  expenseCategory: ExpenseCategoryId
  deductionPct: ValidDeductionPct
  deductionConfidence: number
  reasoningHe: string
  reasoningEn: string
}

interface RawTaxEvalResponse {
  expense_category?: string
  deduction_pct?: number
  deduction_confidence?: number
  reasoning_he?: string
  reasoning_en?: string
}

const VALID_CATEGORIES: ExpenseCategoryId[] = [
  'office', 'marketing', 'professional', 'vehicle', 'equipment',
  'finance', 'welfare', 'exceptional', 'travel',
]

export async function evaluateDeductibility(
  ctx: AICtx,
  expense: Expense,
  businessCategory: string | null,
): Promise<TaxEvalResult> {
  const userPrompt = buildTaxEvalUserPrompt({
    vendorName: expense.vendorName,
    invoiceTotal: expense.invoiceTotal,
    currency: expense.currency,
    amount: expense.amount,
    rawOcrText: expense.rawOcrText,
    businessCategory,
  })

  const response = await callAI(ctx, {
    tenantId: expense.tenantId,
    userId: expense.createdBy,
    useCase: 'expense_tax_eval',
    entityType: 'expense',
    entityId: expense.id,
    tier: 'business',
    messages: [
      {
        role: 'user',
        content: userPrompt,
      },
    ],
    maxTokens: 512,
  })

  // Parse JSON response
  let parsed: RawTaxEvalResponse
  try {
    const text = response.content
    const cleaned = text.replace(/```json\n?/g, '').replace(/```\n?/g, '').trim()
    parsed = JSON.parse(cleaned) as RawTaxEvalResponse
  } catch {
    throw new ExpenseProcessingError('Tax evaluation response was not valid JSON', 'terminal')
  }

  // Validate category
  const category = parsed.expense_category as ExpenseCategoryId | undefined
  if (!category || !VALID_CATEGORIES.includes(category)) {
    throw new ExpenseProcessingError(
      `Invalid expense_category: ${parsed.expense_category}`,
      'terminal',
    )
  }

  // Validate deduction_pct
  const rawPct = parsed.deduction_pct
  if (typeof rawPct !== 'number' || !(VALID_DEDUCTION_PCTS as readonly number[]).includes(rawPct)) {
    throw new ExpenseProcessingError(
      `Invalid deduction_pct: ${rawPct}. Must be one of: 0, 25, 45, 66, 100`,
      'terminal',
    )
  }

  // Validate confidence
  const confidence = parsed.deduction_confidence ?? 0.5
  const clampedConfidence = Math.max(0.5, Math.min(1.0, confidence))

  const reasoningHe = parsed.reasoning_he ?? ''
  const reasoningEn = parsed.reasoning_en ?? ''

  if (!reasoningHe || !reasoningEn) {
    throw new ExpenseProcessingError('Tax evaluation missing reasoning fields', 'terminal')
  }

  return {
    expenseCategory: category,
    deductionPct: rawPct as ValidDeductionPct,
    deductionConfidence: clampedConfidence,
    reasoningHe,
    reasoningEn,
  }
}
