import { HttpStatus } from '@nestjs/common';

export type PlanLimitValue = number | 'unlimited';

function getKvValue(features: unknown, key: string): string | null {
  if (!Array.isArray(features)) return null;
  const rec = features.find((f) => {
    if (!f || typeof f !== 'object') return false;
    return (f as Record<string, unknown>).k === key;
  }) as Record<string, unknown> | undefined;
  const v = typeof rec?.v === 'string' ? rec.v : null;
  return v ? v.trim() : null;
}

function anyKvValue(features: unknown, keys: string[]): string | null {
  for (const k of keys) {
    const v = getKvValue(features, k);
    if (v) return v;
  }
  return null;
}

export function parseAddStoresLimit(features: unknown): PlanLimitValue {
  const v = anyKvValue(features, ['Add Stores', 'Add Store']);
  if (!v) return 0;
  const lower = v.toLowerCase();
  // Legacy BASIC plans were seeded with "No" before the limit was revised to 1.
  if (lower === 'no') return 1;
  if (lower === 'unlimited') return 'unlimited';
  const m = lower.match(/upto\s+(\d+)/);
  if (m) return Number(m[1]);
  return 0;
}

export function parseTeamsLimit(features: unknown): PlanLimitValue {
  const v = anyKvValue(features, [
    'Teams & Roles',
    'Teams and Roles',
    'Teams And Roles',
  ]);
  if (!v) return 0;
  const lower = v.toLowerCase();
  if (lower === 'no') return 0;
  if (lower === 'unlimited') return 'unlimited';
  const m = lower.match(/upto\s+(\d+)/);
  if (m) return Number(m[1]);
  return 0;
}

export function supportsGoogleReviews(features: unknown): boolean {
  const v = anyKvValue(features, ['Reviews']);
  if (!v) return false;
  return v.toLowerCase().includes('google');
}

export function parseMonthlyLimit(
  features: unknown,
  key: 'Coupons' | 'Lucky Draw',
): PlanLimitValue {
  const v = anyKvValue(features, [key, key.toLowerCase(), key.toUpperCase()]);
  if (!v) return 0;
  const lower = v.toLowerCase();
  if (lower === 'no') return 0;
  if (lower === 'unlimited') return 'unlimited';
  const m = lower.match(/(\d+)\s*\/\s*month/);
  if (m) return Number(m[1]);
  const m2 = lower.match(/(\d+)\s*\/\s*months?/);
  if (m2) return Number(m2[1]);
  const m3 = lower.match(/^(\d+)\s*\/\s*month$/);
  if (m3) return Number(m3[1]);
  return 0;
}

export function inferUpgradeTo(
  planCode: string | null | undefined,
): string | null {
  const code = String(planCode ?? '').toUpperCase();
  if (code === 'BASIC') return 'GROWTH';
  if (code === 'GROWTH') return 'PRO';
  return null;
}

export function planLimitPayload(args: {
  featureKey: string;
  currentPlanCode: string | null | undefined;
  limit: PlanLimitValue;
  used?: number;
  period?: 'MONTH' | 'ALWAYS';
}) {
  return {
    statusCode: HttpStatus.PAYMENT_REQUIRED,
    code: 'PLAN_LIMIT',
    featureKey: args.featureKey,
    currentPlanCode: args.currentPlanCode
      ? String(args.currentPlanCode).toUpperCase()
      : null,
    upgradeTo: inferUpgradeTo(args.currentPlanCode),
    limit: args.limit,
    used: args.used ?? null,
    period: args.period ?? 'ALWAYS',
    message: 'Upgrade your plan to continue',
  };
}
