import { supabase } from "@/integrations/supabase/client";
import { loadStripe } from "@stripe/stripe-js";

/**
 * Client wrappers around the `stripe-financial-connections` Edge Function.
 * Replaces the old Plaid bank-feed integration with Stripe Financial Connections.
 * The function holds no secrets itself — it reads the association's Stripe keys
 * from public.stripe_account_mappings (same as the payment functions).
 */
async function invoke<T>(body: Record<string, unknown>): Promise<T> {
  const { data, error } = await supabase.functions.invoke("stripe-financial-connections", { body });
  if (error) {
    const ctx: any = (error as any).context;
    let msg = error.message;
    try { const b = ctx && (await ctx.json?.()); if (b?.error) msg = b.error; } catch { /* ignore */ }
    throw new Error(msg || "Stripe request failed.");
  }
  if ((data as any)?.error) throw new Error((data as any).error);
  return data as T;
}

export function createFcSession(companyId: string) {
  return invoke<{ client_secret: string; publishable_key: string | null; fc_customer_id: string; stripe_account: string | null }>({ action: "create_session", companyId });
}
export function saveFcAccount(input: {
  companyId: string; accountId: string; fc_account_id: string; fc_customer_id?: string;
  institution_name?: string; last4?: string;
}) {
  return invoke<{ success: boolean }>({ action: "save_account", ...input });
}
export function syncStripeTransactions(companyId: string, accountId?: string) {
  return invoke<{ added: number; skipped: number; errors: string[] }>({ action: "sync", companyId, accountId });
}
export function disconnectStripe(accountId: string) {
  return invoke<{ success: boolean }>({ action: "disconnect", accountId });
}

/**
 * Runs the full Stripe Financial Connections linking flow for one ledger bank
 * account: create a session server-side, open Stripe's account picker, then
 * persist the chosen account so it can be synced.
 */
export async function linkBankAccount(companyId: string, accountId: string): Promise<{ linked: number; institution?: string }> {
  const { client_secret, publishable_key, fc_customer_id, stripe_account } = await createFcSession(companyId);
  if (!publishable_key) throw new Error("Stripe publishable key isn't configured for this association.");
  const stripe = await loadStripe(publishable_key, stripe_account ? { stripeAccount: stripe_account } : undefined);
  if (!stripe) throw new Error("Failed to load Stripe.js.");
  const result = await (stripe as any).collectFinancialConnectionsAccounts({ clientSecret: client_secret });
  if (result.error) throw new Error(result.error.message);
  const accounts = result.financialConnectionsSession?.accounts ?? [];
  if (!accounts.length) return { linked: 0 };
  const a = accounts[0];
  await saveFcAccount({
    companyId, accountId, fc_account_id: a.id, fc_customer_id,
    institution_name: a.institution_name, last4: a.last4,
  });
  return { linked: accounts.length, institution: a.institution_name };
}
