// Sofia Client — SDK frontend pra chamar a Edge Function `sofia-chat`.
//
// Expõe window.SofiaAPI com:
//   chat(messages, userState, newMessage)   → Promise<{ reply, mode, usage }>
//   buildUserState(state, userName)         → resumo enxuto pro prompt
//   getMonthlyUsage()                       → para o admin
//
// Comportamento:
// - Se Supabase não configurado OU Edge Function não disponível OU
//   resposta veio com mode='mock' → cai pro fallback local (pickReply).
// - Rate-limit excedido (HTTP 429) → devolve a mensagem amiga da Sofia
//   ao invés de erro técnico.

(function () {
  const FUNCTION_NAME = "sofia-chat";

  // ── Fallback local (mock) ──────────────────────────────────
  function pickMockReply(q) {
    const lower = (q || "").toLowerCase();
    if (lower.includes("semana"))
      return "Sua semana foi sólida! ✨ Quando a Sofia estiver 100% online consigo te trazer números reais. Por enquanto: continue assim que tá bom.";
    if (lower.includes("gast") || lower.includes("dinheiro"))
      return "Quando a IA tiver a chave configurada consigo analisar seu padrão de gastos em detalhe. Por agora: cuidado com a categoria que mais cresceu nos últimos 30 dias.";
    if (lower.includes("estudo") || lower.includes("inglês"))
      return "Posso montar um plano completo de estudos quando estiver totalmente ativa. Comece com 30 min/dia que já é um ótimo ritmo.";
    if (lower.includes("hábito") || lower.includes("habito"))
      return "Hábitos consistentes valem mais do que hábitos intensos. Foque em 1 ou 2 e mantenha a corrente acesa 🔥";
    if (lower.includes("meta") || lower.includes("objetivo"))
      return "Metas grandes ficam mais leves quando você quebra em passos semanais. Que tal escolher 1 ação concreta pra essa semana?";
    return "Anotado! Quando a Sofia estiver totalmente conectada, vou te dar respostas com dados reais do seu app. Algo mais? ✨";
  }

  // ── Helpers ────────────────────────────────────────────────
  function client() {
    if (window.Auth && typeof window.Auth._client === "function") {
      return window.Auth._client();
    }
    return null;
  }

  function isConfigured() {
    return !!client();
  }

  // Reduz o state do app a um resumo de baixo custo pra Sofia
  function buildUserState(state, userName) {
    if (!state) return { userName };
    const today = new Date().toISOString().slice(0, 10);
    const tasks = state.tasks || [];
    const tasksOpen = tasks.filter((t) => !t.done).length;
    const tasksToday = tasks
      .filter((t) => !t.done && (t.date === today || t.dueToday))
      .slice(0, 5)
      .map((t) => t.title);

    const habits = (state.habits || [])
      .filter((h) => !h.archived)
      .slice(0, 5)
      .map((h) => ({ name: h.name, streak: h.streak || 0 }));

    const goals = (state.goals || [])
      .filter((g) => !g.completed)
      .slice(0, 4)
      .map((g) => ({
        title: g.title,
        progress: typeof g.progress === "number" ? Math.round(g.progress) : 0,
      }));

    const finance = state.finance || {};
    const txs = finance.transactions || [];
    let income = 0;
    let expense = 0;
    const catTotals = {};
    const thisMonth = today.slice(0, 7);
    txs.forEach((tx) => {
      if (typeof tx.date === "string" && tx.date.slice(0, 7) !== thisMonth) return;
      const v = Number(tx.amount) || 0;
      if (tx.type === "income") income += v;
      else expense += Math.abs(v);
      if (tx.category) catTotals[tx.category] = (catTotals[tx.category] || 0) + Math.abs(v);
    });
    const topCategory = Object.entries(catTotals).sort((a, b) => b[1] - a[1])[0]?.[0];

    // Cofre — dados sensíveis (o usuário pediu pra Sofia poder consultar)
    // Incluímos tudo do cofre, mas o system prompt orienta a Sofia a tratar
    // como informação sensível: só revelar quando explicitamente perguntado,
    // nunca repetir sem necessidade.
    const vault = (state.vault || []).map(v => ({
      type: v.type,                    // 'senha' | 'conta' | 'email' | 'nota'
      title: v.title,
      site: v.site, user: v.user, password: v.password,
      banco: v.banco, agencia: v.agencia, conta: v.conta, tipoConta: v.tipoConta,
      provedor: v.provedor, email: v.email,
      notes: v.notes, text: v.text,
    }));

    return {
      userName,
      tasksOpen,
      tasksToday,
      habitsActive: habits,
      goalsActive: goals,
      financeMonth: {
        income: Math.round(income),
        expense: Math.round(expense),
        topCategory,
      },
      streak: state.streak || 0,
      level: state.level || 1,
      vault,
    };
  }

  // ── Chat ───────────────────────────────────────────────────
  async function chat({ messages = [], userState, newMessage }) {
    const c = client();
    // Sem Supabase → mock direto
    if (!c) {
      return { reply: pickMockReply(newMessage), mode: "mock", usage: null };
    }

    try {
      const { data, error } = await c.functions.invoke(FUNCTION_NAME, {
        body: { messages, userState, newMessage },
      });

      // Erro de rede / função não deployed
      if (error) {
        console.warn("[Sofia] function error:", error.message);
        return { reply: pickMockReply(newMessage), mode: "mock", usage: null };
      }

      // Rate-limit 429 (Edge Function devolve mensagem amiga)
      if (data && data.error === "rate_limit") {
        return {
          reply: data.message || "Você atingiu o limite de hoje. Volto amanhã ✨",
          mode: "rate_limit",
          usage: { dailyLimit: data.limit, used: data.used },
        };
      }

      // Função respondeu mas sem chave OpenAI configurada
      if (data && data.mode === "mock") {
        return { reply: pickMockReply(newMessage), mode: "mock", usage: null };
      }

      // Erro na chamada OpenAI
      if (data && data.error) {
        console.warn("[Sofia] api error:", data.detail);
        return { reply: pickMockReply(newMessage), mode: "mock", usage: null };
      }

      // Sucesso
      return {
        reply: data.reply,
        mode: data.mode || "live",
        usage: data.usage || null,
      };
    } catch (e) {
      console.warn("[Sofia] crash:", e.message);
      return { reply: pickMockReply(newMessage), mode: "mock", usage: null };
    }
  }

  // ── Métricas de uso (pro painel admin) ─────────────────────
  async function getMonthlyUsage() {
    const c = client();
    if (!c) return null;
    const { data, error } = await c
      .from("ai_usage_monthly")
      .select("*")
      .limit(12);
    if (error) {
      console.warn("[Sofia] usage fetch:", error.message);
      return null;
    }
    return data;
  }

  async function getCurrentMonthCost() {
    const c = client();
    if (!c) return { cost: 0, calls: 0, users: 0 };
    const first = new Date();
    first.setDate(1);
    first.setHours(0, 0, 0, 0);
    const { data, error } = await c
      .from("ai_usage")
      .select("cost_usd, user_id")
      .gte("created_at", first.toISOString());
    if (error) {
      console.warn("[Sofia] month cost:", error.message);
      return { cost: 0, calls: 0, users: 0 };
    }
    const cost = (data || []).reduce((s, r) => s + Number(r.cost_usd || 0), 0);
    const users = new Set((data || []).map((r) => r.user_id)).size;
    return { cost, calls: (data || []).length, users };
  }

  window.SofiaAPI = {
    chat,
    buildUserState,
    getMonthlyUsage,
    getCurrentMonthCost,
    isConfigured,
    pickMockReply,
  };
})();
