import { db } from '@server/db/drizzle';
import { sql } from 'drizzle-orm';
import { AppError } from '@server/errors';

export async function hasPlanFeature(restaurantId: string, feature: string): Promise<boolean> {
  const { rows } = await db.execute(sql`
    SELECT p.features
    FROM subscriptions s
    LEFT JOIN plans p ON s.plan_id = p.id
    WHERE s.restaurant_id = ${restaurantId}
      AND s.status IN ('active','trial')
    ORDER BY s.created_at DESC
    LIMIT 1
  `);
  const raw = (rows[0] as { features?: unknown } | undefined)?.features;
  let features: unknown = raw;
  if (typeof raw === 'string') {
    try { features = JSON.parse(raw); } catch { features = []; }
  }
  if (!Array.isArray(features)) return false;
  return (features as unknown[]).some((f) => typeof f === 'string' && f === feature);
}

export async function requirePlanFeature(restaurantId: string, feature: string): Promise<void> {
  const ok = await hasPlanFeature(restaurantId, feature);
  if (!ok) {
    throw new AppError(
      `Your current plan does not include the "${feature}" feature. Upgrade to enable it.`,
      402,
      'PLAN_FEATURE_REQUIRED'
    );
  }
}

export type PlanLimits = {
  conversations_per_month: number | null;
  api_calls_per_minute: number | null;
  concurrent_voice_calls: number | null;
  max_branches: number | null;
};

function parseLimit(val: unknown): number | null {
  if (val === null || val === undefined) return null;
  const n = Number(val);
  if (!isFinite(n) || n < 0) return null;
  return n;
}

export async function getPlanLimits(restaurantId: string): Promise<PlanLimits> {
  const { rows } = await db.execute(sql`
    SELECT p.limits
    FROM subscriptions s
    LEFT JOIN plans p ON s.plan_id = p.id
    WHERE s.restaurant_id = ${restaurantId}
      AND s.status IN ('active','trial')
    ORDER BY s.created_at DESC
    LIMIT 1
  `);
  const raw = (rows[0] as { limits?: unknown } | undefined)?.limits;
  let limits: Record<string, unknown> = {};
  if (typeof raw === 'string') {
    try { limits = JSON.parse(raw); } catch { limits = {}; }
  } else if (raw && typeof raw === 'object') {
    limits = raw as Record<string, unknown>;
  }
  return {
    conversations_per_month: parseLimit(limits.conversations_per_month),
    api_calls_per_minute: parseLimit(limits.api_calls_per_minute),
    concurrent_voice_calls: parseLimit(limits.concurrent_voice_calls),
    max_branches: parseLimit(limits.max_branches),
  };
}
