import { randomBytes } from "crypto";
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
import path from "path";
import { fileURLToPath } from "url";

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const DATA_DIR = path.join(__dirname, "../../data");
const KEYS_FILE = path.join(DATA_DIR, "keys.json");

export interface ApiKey {
  key: string;
  tier: "free" | "pro";
  email: string;
  createdAt: string;
  stripeCustomerId?: string;
}

interface KeyStore {
  keys: ApiKey[];
}

let store: KeyStore = { keys: [] };

function ensureDataDir(): void {
  if (!existsSync(DATA_DIR)) {
    mkdirSync(DATA_DIR, { recursive: true });
  }
}

export function loadKeys(): void {
  ensureDataDir();
  if (existsSync(KEYS_FILE)) {
    try {
      store = JSON.parse(readFileSync(KEYS_FILE, "utf-8"));
    } catch {
      store = { keys: [] };
    }
  }
  // Also load seed keys from env
  const envKeys = process.env.API_KEYS?.split(",").map((k) => k.trim()).filter(Boolean) || [];
  for (const k of envKeys) {
    if (!store.keys.find((e) => e.key === k)) {
      store.keys.push({ key: k, tier: "pro", email: "seed@docfast.dev", createdAt: new Date().toISOString() });
    }
  }
}

function save(): void {
  ensureDataDir();
  writeFileSync(KEYS_FILE, JSON.stringify(store, null, 2));
}

export function isValidKey(key: string): boolean {
  return store.keys.some((k) => k.key === key);
}

export function getKeyInfo(key: string): ApiKey | undefined {
  return store.keys.find((k) => k.key === key);
}

export function isProKey(key: string): boolean {
  const info = getKeyInfo(key);
  return info?.tier === "pro";
}

function generateKey(prefix: string): string {
  return `${prefix}_${randomBytes(24).toString("hex")}`;
}

export function createFreeKey(email: string): ApiKey {
  // Check if email already has a free key
  const existing = store.keys.find((k) => k.email === email && k.tier === "free");
  if (existing) return existing;

  const entry: ApiKey = {
    key: generateKey("df_free"),
    tier: "free",
    email,
    createdAt: new Date().toISOString(),
  };
  store.keys.push(entry);
  save();
  return entry;
}

export function createProKey(email: string, stripeCustomerId: string): ApiKey {
  const existing = store.keys.find((k) => k.stripeCustomerId === stripeCustomerId);
  if (existing) {
    existing.tier = "pro";
    save();
    return existing;
  }

  const entry: ApiKey = {
    key: generateKey("df_pro"),
    tier: "pro",
    email,
    createdAt: new Date().toISOString(),
    stripeCustomerId,
  };
  store.keys.push(entry);
  save();
  return entry;
}

export function revokeByCustomer(stripeCustomerId: string): boolean {
  const idx = store.keys.findIndex((k) => k.stripeCustomerId === stripeCustomerId);
  if (idx >= 0) {
    store.keys.splice(idx, 1);
    save();
    return true;
  }
  return false;
}

export function getAllKeys(): ApiKey[] {
  return [...store.keys];
}
