import GasStationModel from "../models/GasStationModel";
import { getStripe, stripeConfig } from "../config/stripe";

export type GasStationStripeFlags = {
  stripeConnected: boolean;
  isStripeConnected: boolean;
  stripeChargesEnabled: boolean;
  stripeDetailsSubmitted: boolean;
  stripeStatus: "active" | "pending" | "connect_required";
};

export function stripeFlagsFromGasStation(doc: {
  stripeConnected?: boolean;
  stripeChargesEnabled?: boolean;
  stripeDetailsSubmitted?: boolean;
}): GasStationStripeFlags {
  const chargesEnabled = Boolean(doc.stripeChargesEnabled);
  const detailsSubmitted = Boolean(doc.stripeDetailsSubmitted);
  const stripeConnected = Boolean(doc.stripeConnected || detailsSubmitted);
  const stripeStatus: GasStationStripeFlags["stripeStatus"] = chargesEnabled
    ? "active"
    : stripeConnected || detailsSubmitted
      ? "pending"
      : "connect_required";

  return {
    stripeConnected: stripeConnected || chargesEnabled,
    isStripeConnected: chargesEnabled,
    stripeChargesEnabled: chargesEnabled,
    stripeDetailsSubmitted: detailsSubmitted,
    stripeStatus,
  };
}

/** Pull Connect account state from Stripe and persist on GasStation. */
export async function syncGasStationStripeStatusForUser(
  userId: string,
): Promise<GasStationStripeFlags> {
  if (!stripeConfig.secretKey) {
    throw new Error("Stripe is not configured");
  }
  const gasStation = await GasStationModel.findOne({ userId });
  if (!gasStation) {
    throw new Error("No gas station registered");
  }
  if (!gasStation.stripeAccountId) {
    return {
      stripeConnected: false,
      isStripeConnected: false,
      stripeChargesEnabled: false,
      stripeDetailsSubmitted: false,
      stripeStatus: "connect_required",
    };
  }

  const stripe = getStripe();
  const account = await stripe.accounts.retrieve(gasStation.stripeAccountId);
  const detailsSubmitted = account.details_submitted ?? false;
  const chargesEnabled = account.charges_enabled ?? false;

  gasStation.stripeDetailsSubmitted = detailsSubmitted;
  gasStation.stripeChargesEnabled = chargesEnabled;
  gasStation.stripeConnected = detailsSubmitted;
  await gasStation.save();

  return stripeFlagsFromGasStation(gasStation);
}

/** Best-effort sync when reading login / my-station (no throw). */
export async function trySyncGasStationStripeStatus(userId: string): Promise<void> {
  if (!stripeConfig.secretKey) return;
  const linked = await GasStationModel.findOne({ userId })
    .select("stripeAccountId")
    .lean();
  if (!linked?.stripeAccountId) return;
  try {
    await syncGasStationStripeStatusForUser(userId);
  } catch (err) {
    console.warn(
      "[gas-station] Stripe sync on read failed:",
      err instanceof Error ? err.message : err,
    );
  }
}
