import { PrismaClient } from "@prisma/client";
import * as bcryptjs from "bcryptjs";
import * as fs from "fs";
import * as path from "path";

/**
 * Seeds a fresh database with:
 *   1. The default `admin@local` user (password: `workout123`).
 *   2. Default UserPreferences for that user.
 *   3. The full curated exercise library, loaded from
 *      `prisma/exercises.seed.json`.
 *
 * Idempotent — re-running upserts the user and exercises without
 * duplicates. Used at Docker build time to populate the empty-schema
 * fallback DB and at first boot for any host that didn't get a baked seed.
 *
 * The curated library is the same JSON read at runtime by
 * `ensureExerciseLibrary.cjs` from docker_entrypoint.sh, so updates
 * shipped in a new package version reach existing installs too.
 */

const prisma = new PrismaClient();

interface LibraryExercise {
  name: string;
  description: string | null;
  type: string;
  muscleGroups: string[];
  inputFields: string[];
  defaultWeightUnit: string | null;
}

function loadLibrary(): LibraryExercise[] {
  const libPath = path.resolve(__dirname, "exercises.seed.json");
  if (!fs.existsSync(libPath)) {
    console.warn(`[seed] library file not found at ${libPath}; seeding 0 exercises`);
    return [];
  }
  const raw = JSON.parse(fs.readFileSync(libPath, "utf8"));
  if (!Array.isArray(raw)) {
    throw new Error(`[seed] library file at ${libPath} is not an array`);
  }
  return raw as LibraryExercise[];
}

async function main() {
  const hashedPassword = await bcryptjs.hash("workout123", 10);

  const user = await prisma.user.upsert({
    where: { email: "admin@local" },
    update: { isAdmin: true },
    create: {
      email: "admin@local",
      passwordHash: hashedPassword,
      name: "Admin User",
      isAdmin: true,
    },
  });

  console.log("Created/verified admin user:", user.id);

  await prisma.instanceSettings.upsert({
    where: { id: 1 },
    update: {},
    create: { id: 1, signupsOpen: false },
  });

  console.log("Created/verified InstanceSettings (signupsOpen: false)");

  await prisma.userPreferences.upsert({
    where: { userId: user.id },
    update: {},
    create: {
      userId: user.id,
      theme: "system",
      defaultWeightUnit: "lbs",
      defaultRestSeconds: 90,
      enableClaudeAI: false,
    },
  });

  console.log("Created/verified user preferences");

  const exercises = loadLibrary();
  console.log(`[seed] loading ${exercises.length} exercises from exercises.seed.json`);

  for (const exercise of exercises) {
    await prisma.exercise.upsert({
      where: {
        userId_name: {
          userId: user.id,
          name: exercise.name,
        },
      },
      update: {},
      create: {
        userId: user.id,
        name: exercise.name,
        description: exercise.description,
        muscleGroups: JSON.stringify(exercise.muscleGroups),
        type: exercise.type,
        inputFields: JSON.stringify(exercise.inputFields),
        defaultWeightUnit: exercise.defaultWeightUnit,
        isCustom: false,
      },
    });
  }

  console.log(`Created/verified ${exercises.length} exercises`);
}

main()
  .then(async () => {
    await prisma.$disconnect();
  })
  .catch(async (e) => {
    console.error(e);
    await prisma.$disconnect();
    process.exit(1);
  });
