import { LlmProvider, LlmRequest, LlmResponse } from './llm.provider';

/**
 * Deterministic stand-in for development and automated tests (AI_PROVIDER=mock).
 * It never calls a network. Behaviour is keyed off the system prompt so the
 * full intake -> proposal -> accept path and the copilot tool loop can be
 * exercised end-to-end without an API key. Not for production.
 */
export class MockProvider implements LlmProvider {
  readonly name = 'mock';
  readonly model = 'mock-1';

  async complete(req: LlmRequest): Promise<LlmResponse> {
    const last = req.messages[req.messages.length - 1];
    const lastText = typeof last?.content === 'string' ? last.content : '';
    const usage = { inputTokens: Math.ceil((req.system.length + lastText.length) / 4), outputTokens: 50 };

    // Copilot: one tool round, then an answer built from the tool result.
    if (req.tools?.length) {
      if (Array.isArray(last?.content) && last.content.some((b) => b.type === 'tool_result')) {
        const r = last.content.find((b) => b.type === 'tool_result') as { content: string } | undefined;
        return { text: `Mock answer based on tool data: ${(r?.content ?? '').slice(0, 300)}`, toolCalls: [], stopReason: 'end', usage, model: this.model };
      }
      const q = lastText.toLowerCase();
      const name = q.includes('order') ? 'find_orders' : q.includes('asn') || q.includes('deliver') ? 'find_asns' : q.includes('task') ? 'task_queue' : q.includes('expir') ? 'expiry_report' : 'get_dashboard';
      return { text: '', toolCalls: [{ id: `toolu_mock_${Date.now()}`, name, input: {} }], stopReason: 'tool_use', usage, model: this.model };
    }

    if (req.json) {
      if (req.system.includes('supplier correspondence')) {
        return { text: JSON.stringify({ subject: 'Receiving discrepancies on your delivery', bodyHtml: '<p>Dear supplier,</p><p>Please find below the discrepancies recorded at receipt.</p><table><tr><td>see attached</td></tr></table><p>Kindly issue a credit note.</p>' }), toolCalls: [], stopReason: 'end', usage, model: this.model };
      }
      const isAsn = req.system.includes('supplier delivery');
      const doc = lastText.split('Document text:')[1] ?? lastText;
      const ref = /(?:PO|ORDER|SO|REF)[\s#:-]*([A-Z0-9-]{3,})/i.exec(doc)?.[1];
      const lines: Record<string, unknown>[] = [];
      for (const line of doc.split('\n')) {
        const m = /^\s*([A-Z][A-Z0-9-]{2,})\s+(?:x\s*)?(\d+(?:\.\d+)?)\s*([A-Za-z]{2,4})?/.exec(line.trim());
        if (m) lines.push({ itemCode: m[1], qty: Number(m[2]), uom: m[3]?.toUpperCase(), confidence: 0.9 });
      }
      const date = /(\d{4}-\d{2}-\d{2})/.exec(doc)?.[1];
      const body = isAsn
        ? { reference: ref, supplierName: /supplier[:\s]+([^\n]+)/i.exec(doc)?.[1]?.trim(), expectedDate: date, lines, warnings: lines.length ? [] : ['No lines recognised'] }
        : { reference: ref, customerName: /customer[:\s]+([^\n]+)/i.exec(doc)?.[1]?.trim(), requestedShipDate: date, lines: lines.map((l) => ({ ...l, serials: [] })), warnings: lines.length ? [] : ['No lines recognised'] };
      return { text: JSON.stringify(body), toolCalls: [], stopReason: 'end', usage, model: this.model };
    }

    return { text: `Mock narrative. ${lastText.slice(0, 120)}`, toolCalls: [], stopReason: 'end', usage, model: this.model };
  }
}
