export interface ReferralClientOptions {
  baseUrl: string;
  productId: string;
  getAccessToken: () => string;
}

export interface ReferralStats {
  totalReferrals: number;
  successfulReferrals: number;
  pendingReferrals: number;
  rewardsEarned: number;
  referralCode: string;
}

export interface ReferralInfo {
  code: string;
  referrerEmail: string;
  status: string;
}

function joinUrl(base: string, path: string): string {
  const b = base.replace(/\/$/, "");
  const p = path.startsWith("/") ? path : `/${path}`;
  return `${b}${p}`;
}

function headers(opts: ReferralClientOptions): HeadersInit {
  return {
    Authorization: `Bearer ${opts.getAccessToken()}`,
    "X-Product-Id": opts.productId,
    Accept: "application/json",
  };
}

async function parseJson<T>(res: Response): Promise<T> {
  if (!res.ok) {
    const text = await res.text();
    throw new Error(`HTTP ${res.status}: ${text || res.statusText}`);
  }
  return res.json() as Promise<T>;
}

export function createReferralClient(opts: ReferralClientOptions) {
  const { baseUrl } = opts;

  return {
    async getReferralStats(): Promise<ReferralStats> {
      const res = await fetch(joinUrl(baseUrl, "/referrals/stats"), {
        method: "GET",
        headers: headers(opts),
      });
      return parseJson<ReferralStats>(res);
    },

    buildShareLink(code: string): string {
      const b = baseUrl.replace(/\/$/, "");
      return `${b}/r/${code}`;
    },

    buildShareMessage(code: string, productName: string): string {
      return `Try ${productName}! Use my referral code: ${code}`;
    },

    async getByEmail(code: string): Promise<ReferralInfo> {
      const res = await fetch(
        joinUrl(baseUrl, `/referrals/${encodeURIComponent(code)}`),
        { method: "GET", headers: headers(opts) }
      );
      return parseJson<ReferralInfo>(res);
    },
  };
}
