// Sistema de planos (Free vs Pro) + limites e modal de upgrade.
// Plano persistido no Supabase (tabela profiles, view user_plan).
// Cliente NÃO consegue virar Pro sozinho — só via RPC dev_set_plan (DEV)
// ou webhook Stripe (PRODUÇÃO, futuro).

const FREE_LIMITS = {
  workspaces: 1,
  manualTxnsPerMonth: 50,
  invoiceImportsPerMonth: 1,
  spreadsheetImports: 0,
  chatMessagesPerDay: 10,
  historyMonths: 3,
  diagnosisAI: false,
  mobileMode: false,
  csvExport: false,
  recurringClients: false,
  darkTheme: false,
};

// Cache em memória (evita refetch desnecessário)
let _planCache = null;
let _planCacheUserId = null;

// Hook: { plan, isPro, setPlan(devOnly), refresh, loading }
function usePlan(userId) {
  const [plan, setPlanState] = React.useState(() => {
    if (_planCacheUserId === userId && _planCache) return _planCache;
    return "free";
  });
  const [loading, setLoading] = React.useState(!_planCache || _planCacheUserId !== userId);

  const refresh = React.useCallback(async () => {
    if (!userId || !window.db?.getPlan) return;
    setLoading(true);
    try {
      const result = await window.db.getPlan();
      _planCache = result.plan;
      _planCacheUserId = userId;
      setPlanState(result.plan);
    } catch (e) {
      console.error("[plan] refresh failed", e);
    } finally {
      setLoading(false);
    }
  }, [userId]);

  React.useEffect(() => {
    if (userId) refresh();
  }, [userId, refresh]);

  // [DEV] Toggle direto via RPC. Em prod isso vira no-op + redireciona pra Stripe.
  const setPlan = React.useCallback(async (newPlan) => {
    if (!userId || !window.db?.devSetPlan) return;
    try {
      await window.db.devSetPlan(newPlan);
      _planCache = newPlan;
      _planCacheUserId = userId;
      setPlanState(newPlan);
    } catch (e) {
      console.error("[plan] setPlan failed", e);
      alert("Falha ao alterar plano. Verifique se a migration 005_plan.sql foi aplicada no Supabase.\n\nDetalhe: " + (e?.message || e));
    }
  }, [userId]);

  return {
    plan,
    isPro: plan === "pro",
    loading,
    refresh,
    setPlan,
  };
}

// ===== Contadores de uso (resetam por mês/dia) =====

// Quantos lançamentos manuais o usuário criou no mês corrente.
// Usa created_at quando disponível; senão considera todos.
function countManualTxnsThisMonth(ws) {
  const now = new Date();
  const y = now.getFullYear();
  const m = now.getMonth();
  const all = [
    ...(ws.transactions || []),
    ...(ws.receitas || []),
  ];
  return all.filter(t => {
    // Conta pelo created_at (ou date como fallback).
    const stamp = t.created_at || t.date;
    if (!stamp) return false;
    const d = new Date(stamp);
    return d.getFullYear() === y && d.getMonth() === m;
  }).length;
}

// Importações de fatura no mês — contador no localStorage por workspace.
function getInvoiceImportsThisMonth(wsKey) {
  if (!wsKey) return 0;
  const k = invoiceImportKey(wsKey);
  try { return parseInt(localStorage.getItem(k) || "0", 10); }
  catch (e) { return 0; }
}
function incrementInvoiceImports(wsKey) {
  if (!wsKey) return;
  const k = invoiceImportKey(wsKey);
  try {
    const cur = parseInt(localStorage.getItem(k) || "0", 10);
    localStorage.setItem(k, String(cur + 1));
  } catch (e) {}
}
function invoiceImportKey(wsKey) {
  const d = new Date();
  return `usage_invoice_${wsKey}_${d.getFullYear()}_${d.getMonth()}`;
}

// Mensagens de chat IA hoje — contador no localStorage por user.
function getChatMessagesToday(userId) {
  if (!userId) return 0;
  const k = chatKey(userId);
  try { return parseInt(localStorage.getItem(k) || "0", 10); }
  catch (e) { return 0; }
}
function incrementChatMessages(userId) {
  if (!userId) return;
  const k = chatKey(userId);
  try {
    const cur = parseInt(localStorage.getItem(k) || "0", 10);
    localStorage.setItem(k, String(cur + 1));
  } catch (e) {}
}
function chatKey(userId) {
  const d = new Date();
  return `usage_chat_${userId}_${d.toISOString().slice(0, 10)}`;
}

// Limpa contadores antigos (rodar 1x por sessão pra evitar lixo)
function cleanupOldUsageCounters() {
  try {
    const today = new Date().toISOString().slice(0, 10);
    const ymCur = `${new Date().getFullYear()}_${new Date().getMonth()}`;
    Object.keys(localStorage).forEach(k => {
      if (k.startsWith("usage_chat_")) {
        const parts = k.split("_");
        const date = parts.slice(-3).join("_").replace(/^_/, "");
        // Chave: usage_chat_USERID_YYYY-MM-DD — pega tudo depois do penúltimo "_"
        const datePart = k.match(/_(\d{4}-\d{2}-\d{2})$/)?.[1];
        if (datePart && datePart !== today) localStorage.removeItem(k);
      } else if (k.startsWith("usage_invoice_")) {
        const ymPart = k.match(/_(\d{4})_(\d{1,2})$/);
        if (ymPart) {
          const ym = `${ymPart[1]}_${parseInt(ymPart[2], 10)}`;
          if (ym !== ymCur) localStorage.removeItem(k);
        }
      }
    });
  } catch (e) {}
}

// ===== Modal de Upgrade =====
function UpgradeModal({ open, onClose, accent, reason }) {
  const [loadingPlan, setLoadingPlan] = React.useState(null); // "monthly" | "yearly" | null
  const [errorMsg, setErrorMsg] = React.useState("");

  if (!open) return null;

  const handleSubscribe = async (plan) => {
    setErrorMsg("");
    setLoadingPlan(plan);
    try {
      const url = await window.db.createCheckoutSession(plan);
      window.location.href = url;
    } catch (e) {
      console.error("[upgrade] checkout failed", e);
      setErrorMsg(
        (e?.message || String(e)) +
        " — Se a integração ainda não está pronta, ative o Pro em Configurações → Plano (dev)."
      );
      setLoadingPlan(null);
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose} style={{ padding: 20 }}>
      <div className="modal" onClick={e => e.stopPropagation()} style={{ width: 540, maxWidth: "100%", padding: 32 }}>
        <div style={{ display: "flex", alignItems: "flex-start", justifyContent: "space-between", marginBottom: 14 }}>
          <div style={{ display: "flex", alignItems: "center", gap: 12 }}>
            <span style={{ width: 40, height: 40, borderRadius: 12, background: "var(--green)", color: "var(--green-soft)", display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "var(--glow-green)" }}>
              <Icon name="spark" size={18} />
            </span>
            <div>
              <div className="eyebrow" style={{ color: "var(--green)", fontSize: 10.5 }}>// upgrade</div>
              <h3 style={{ margin: "4px 0 0", fontFamily: "'Fraunces', Georgia, serif", fontSize: 26, fontWeight: 400, letterSpacing: "-0.02em", lineHeight: 1.1 }}>
                Você ganharia <em style={{ fontStyle: "italic", fontWeight: 300, color: "var(--green)" }}>tempo</em> com o Pro
              </h3>
            </div>
          </div>
          <button onClick={onClose} className="icon-btn"><Icon name="x" size={16} /></button>
        </div>

        {reason && (
          <div style={{ padding: "10px 14px", background: "var(--warn-bg)", border: "1px solid color-mix(in oklab, var(--warn) 28%, transparent)", borderRadius: 10, fontSize: 13, color: "var(--fg-1)", marginBottom: 18, lineHeight: 1.5 }}>
            {reason}
          </div>
        )}

        {errorMsg && (
          <div style={{ padding: "10px 14px", background: "var(--danger-bg, color-mix(in oklab, var(--danger) 10%, transparent))", border: "1px solid color-mix(in oklab, var(--danger) 38%, transparent)", borderRadius: 10, fontSize: 12.5, color: "var(--fg-1)", marginBottom: 14, lineHeight: 1.5 }}>
            {errorMsg}
          </div>
        )}

        <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 20 }}>
          <PriceCard
            title="Mensal"
            value="14,90"
            sub="cancele quando quiser"
            highlight={false}
            loading={loadingPlan === "monthly"}
            disabled={loadingPlan !== null}
            onClick={() => handleSubscribe("monthly")}
          />
          <PriceCard
            title="Anual"
            value="9,90"
            sub="R$ 119/ano · economiza R$ 60"
            highlight
            badge="−33%"
            loading={loadingPlan === "yearly"}
            disabled={loadingPlan !== null}
            onClick={() => handleSubscribe("yearly")}
          />
        </div>

        <ul style={{ listStyle: "none", padding: 0, margin: 0, display: "flex", flexDirection: "column", gap: 8, fontSize: 13.5, color: "var(--fg-1)", lineHeight: 1.5 }}>
          <li style={{ display: "flex", gap: 8 }}><span style={{ color: "var(--success)" }}>✓</span><span><strong>Tudo desbloqueado, sem limites</strong></span></li>
          <li style={{ display: "flex", gap: 8 }}><span style={{ color: "var(--success)" }}>✓</span><span>Workspaces ilimitados (PF + PJ no mesmo login)</span></li>
          <li style={{ display: "flex", gap: 8 }}><span style={{ color: "var(--success)" }}>✓</span><span>Lançamentos, importações e chat IA ilimitados</span></li>
          <li style={{ display: "flex", gap: 8 }}><span style={{ color: "var(--success)" }}>✓</span><span>Diagnóstico IA + modo mobile + tema escuro</span></li>
          <li style={{ display: "flex", gap: 8 }}><span style={{ color: "var(--success)" }}>✓</span><span>7 dias grátis · sem cartão pra começar</span></li>
        </ul>

        <div style={{ marginTop: 20, paddingTop: 16, borderTop: "1px solid var(--border)", fontSize: 11.5, color: "var(--fg-3)", lineHeight: 1.5 }}>
          Pagamento processado pela Stripe. Cancele a qualquer momento em Configurações → Plano.
        </div>
      </div>
    </div>
  );
}

function PriceCard({ title, value, sub, highlight, badge, onClick, loading, disabled }) {
  return (
    <button onClick={onClick} disabled={disabled} style={{
      padding: 18, borderRadius: 16, border: "1px solid",
      borderColor: highlight ? "var(--green)" : "var(--border)",
      background: highlight ? "color-mix(in oklab, var(--green) 6%, var(--surface-1))" : "var(--surface-1)",
      cursor: disabled ? "wait" : "pointer", textAlign: "left", fontFamily: "inherit",
      position: "relative", transition: "transform .15s ease, box-shadow .25s ease",
      opacity: disabled && !loading ? 0.5 : 1,
    }}
      onMouseEnter={e => { if (disabled) return; e.currentTarget.style.transform = "translateY(-2px)"; e.currentTarget.style.boxShadow = "0 8px 24px -6px color-mix(in oklab, var(--green) 25%, transparent)"; }}
      onMouseLeave={e => { e.currentTarget.style.transform = "none"; e.currentTarget.style.boxShadow = "none"; }}
    >
      {badge && (
        <span style={{ position: "absolute", top: -10, right: 14, padding: "3px 10px", borderRadius: 99, background: "var(--green)", color: "var(--green-soft)", fontSize: 10, fontWeight: 700, letterSpacing: "0.04em" }}>{badge}</span>
      )}
      <div className="eyebrow" style={{ fontSize: 10 }}>{title}</div>
      <div style={{ fontFamily: "'Fraunces', Georgia, serif", fontSize: 36, fontWeight: 500, letterSpacing: "-0.04em", lineHeight: 1, marginTop: 8, color: "var(--fg-1)" }}>
        <span style={{ fontSize: 18, color: "var(--fg-3)", verticalAlign: "top" }}>R$ </span>{value}<span style={{ fontSize: 13, color: "var(--fg-3)", fontWeight: 400, fontFamily: "var(--body, 'Manrope')" }}> /mês</span>
      </div>
      <div style={{ fontSize: 11.5, color: "var(--fg-3)", marginTop: 6 }}>{loading ? "Abrindo Stripe…" : sub}</div>
    </button>
  );
}

// ===== Helpers públicos pro resto do app =====
window.PlanilhaPlan = {
  usePlan,
  FREE_LIMITS,
  countManualTxnsThisMonth,
  getInvoiceImportsThisMonth, incrementInvoiceImports,
  getChatMessagesToday, incrementChatMessages,
  cleanupOldUsageCounters,
  UpgradeModal,
};

// Roda cleanup ao carregar
cleanupOldUsageCounters();
