import type { Lead, Me } from '@repo/kcgm-shared';
export type { Lead, Me };

export const ALL_TOKEN = '*ALL*';
export const RPM_LABEL = 'Reciprocal Partner Clubs (RPM)';
export const NONE_LABEL = 'No Promo Code';

export const REGIONS = ['India', 'SEAP', 'EU_UK_ROW', 'No Country Info'] as const;
export const REGION_COLORS: Record<string, string> = {
  India: '#c2a154', SEAP: '#b89a52', EU_UK_ROW: '#876328', 'No Country Info': '#c9bfa6',
};
export const CONTACT_BUCKETS = ['Phone + Email', 'Phone Only', 'Email Only', 'None'] as const;
export const CONTACT_COLORS: Record<string, string> = {
  'Phone + Email': '#876328', 'Phone Only': '#c2a154', 'Email Only': '#d8c081', 'None': '#ece3c9',
};

export type GMeta = { icon: string; meta: string };
export const GMETA: Record<string, GMeta> = {
  'Social Media Campaigns': { icon: 'globe', meta: 'Paid + organic social' },
  'KEVO Instagram Campaign': { icon: 'globe', meta: 'KEVO Instagram' },
  'Simon Marjoram Campaign': { icon: 'phone', meta: 'Dormant + Toured not Bought' },
  'Karma Cares Campaign': { icon: 'star', meta: 'Karma Cares outreach' },
  'KG Brand Ambassadors': { icon: 'star', meta: 'Ambassador sign-ups' },
  'Reciprocal Partner Clubs (RPM)': { icon: 'users', meta: 'Reciprocal partner clubs' },
  'KG Member Referrals': { icon: 'users', meta: 'Member-to-member' },
  'Retail Guests': { icon: 'tag', meta: 'On-property retail outlets' },
  'No Promo Code': { icon: 'tag', meta: 'Unattributed (KCGM)' },
};
export const gmeta = (g: string): GMeta => GMETA[g] || { icon: 'tag', meta: '' };

/* ---- formatting ---- */
export const fmt = (n: number) => (n || 0).toLocaleString('en-US');
const MON = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
export function parseDate(s: string | null): Date | null {
  if (!s) return null; const d = new Date(s.length <= 10 ? s + 'T00:00:00' : s);
  return isNaN(+d) ? null : d;
}
/** Day-first dd Mon yyyy (en-GB). */
export function fmtDate(s: string | null): string {
  const d = parseDate(s); if (!d) return '—';
  return `${String(d.getDate()).padStart(2, '0')} ${MON[d.getMonth()]} ${d.getFullYear()}`;
}
export function monthLabel(sm: string): string {
  if (!sm || sm === 'ALL') return 'All time';
  const [y, m] = sm.split('-'); const mi = parseInt(m, 10) - 1;
  return `${MON[mi] || m} ${y}`;
}

/* ---- time buckets (by acquisition date) ---- */
const sod = (d: Date) => new Date(d.getFullYear(), d.getMonth(), d.getDate());
export type Bucket = { day: number; week: number; month: number; year: number; all: number };
export const zero = (): Bucket => ({ day: 0, week: 0, month: 0, year: 0, all: 0 });
export type Focus = 'day' | 'week' | 'month' | 'year' | 'all';
export const FOCUS_LABEL: Record<Focus, string> = {
  day: 'Today', week: 'This week', month: 'This month', year: 'This year', all: 'All time',
};
export function buckets(acq: string | null): Bucket {
  const now = new Date();
  const d = parseDate(acq); if (!d) return { day: 0, week: 0, month: 0, year: 0, all: 1 };
  const t = sod(now), dd = sod(d); const w = new Date(t); w.setDate(w.getDate() - 6);
  return {
    day: +dd === +t ? 1 : 0, week: dd >= w && dd <= t ? 1 : 0,
    month: d.getFullYear() === now.getFullYear() && d.getMonth() === now.getMonth() ? 1 : 0,
    year: d.getFullYear() === now.getFullYear() ? 1 : 0, all: 1,
  };
}
export function addB(a: Bucket, l: Lead) { const b = buckets(l.acq); a.day += b.day; a.week += b.week; a.month += b.month; a.year += b.year; a.all += b.all; }
export const periodCount = (rows: Lead[], f: Focus) => (f === 'all' ? rows.length : rows.reduce((s, r) => s + buckets(r.acq)[f], 0));

/* ---- lead helpers ---- */
export const isRpm = (l: Lead) => (l.prefix || '').trim().toUpperCase() === 'RPM';
export function codeOf(l: Lead): { code: string; rpm: boolean } {
  const rpm = isRpm(l);
  const c = (l.promo || '').trim();
  return { code: c || (rpm ? 'Unnamed club' : 'No code'), rpm };
}
export const ccOf = (l: Lead) => (['Phone + Email', 'Phone Only', 'Email Only'].includes(l.contact) ? l.contact : 'None');
export const reachable = (rows: Lead[]) => rows.filter((l) => l.contact === 'Phone + Email').length;
export const pct = (n: number, d: number) => (d ? Math.round((n / d) * 100) : 0);
export const sumPoints = (rows: Lead[]) => rows.reduce((s, r) => s + (r.points || 0), 0);
export const appDownloads = (rows: Lead[]) => rows.filter((l) => isRpm(l) && (l.points || 0) > 0).length;
export function topCode(rows: Lead[]): { code: string; n: number } | null {
  const m: Record<string, number> = {};
  rows.forEach((l) => { const c = codeOf(l).code; m[c] = (m[c] || 0) + 1; });
  const e = Object.entries(m).sort((a, b) => b[1] - a[1])[0];
  return e ? { code: e[0], n: e[1] } : null;
}
export const regionOf = (l: Lead) => (REGIONS as readonly string[]).includes(l.region) ? l.region : 'No Country Info';

/* ---- CSV export ---- */
const CSV_COLS: (keyof Lead)[] = ['id', 'first', 'last', 'country', 'nat', 'dob', 'phone', 'email', 'promo', 'prefix', 'points', 'acq', 'region', 'sm', 'contact'];
const esc = (v: any) => { const s = v == null ? '' : String(v); return /[",\n]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s; };
export function buildCSV(rows: Lead[]): string {
  const head = CSV_COLS.join(',');
  const body = rows.map((r) => CSV_COLS.map((c) => esc((r as any)[c])).join(',')).join('\n');
  return head + '\n' + body;
}
export function downloadCSV(filename: string, rows: Lead[]) {
  const blob = new Blob([buildCSV(rows)], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const a = document.createElement('a'); a.href = url; a.download = filename;
  document.body.appendChild(a); a.click(); a.remove(); URL.revokeObjectURL(url);
}

export const BOOTSTRAP_ADMINS = ['thomas.newton@karmagroup.com', 'clinton.albuquerque@karmagroup.com',];
