import { Exercise } from "@prisma/client";

export type Option = {
  value: string;
  label: string;
};

export const BASE_EQUIPMENT_OPTIONS: Option[] = [
  { value: "barbell", label: "Barbell" },
  { value: "dumbbell", label: "Dumbbell" },
  { value: "machine", label: "Machine" },
  { value: "cable", label: "Cable" },
  { value: "bodyweight", label: "Bodyweight" },
  { value: "cardio", label: "Cardio" },
  { value: "kettlebell", label: "Kettlebell" },
  { value: "other", label: "Other" },
];

export const BASE_MUSCLE_GROUPS: string[] = [
  "chest",
  "back",
  "shoulders",
  "quads",
  "hamstrings",
  "glutes",
  "biceps",
  "triceps",
  "forearms",
  "core",
  "calves",
  "full body",
  "cardio",
  "abs",
  "adductors",
  "legs",
  "traps",
  "hip flexors",
  "neck",
  "obliques",
];

export const BASE_TRACKING_FIELDS: Option[] = [
  { value: "sets", label: "Sets" },
  { value: "reps", label: "Reps" },
  { value: "weight", label: "Weight" },
  { value: "duration", label: "Time" },
  { value: "distance", label: "Distance" },
  { value: "calories", label: "Calories" },
  { value: "notes", label: "Notes" },
];

function titleCaseToken(input: string): string {
  return input
    .split(" ")
    .filter(Boolean)
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(" ");
}

function parseJsonArray(raw: string | null): string[] {
  if (!raw) return [];
  try {
    const parsed = JSON.parse(raw);
    return Array.isArray(parsed) ? parsed.map(String) : [];
  } catch {
    return [];
  }
}

export function normalizeValue(input: string): string {
  return input.trim().toLowerCase().replace(/\s+/g, " ");
}

export function deriveEquipmentOptions(exercises: Exercise[]): Option[] {
  const baseValues = new Set(BASE_EQUIPMENT_OPTIONS.map((item) => item.value));
  const customValues = new Set<string>();

  for (const exercise of exercises) {
    const value = normalizeValue(exercise.type || "");
    if (value && !baseValues.has(value)) {
      customValues.add(value);
    }
  }

  const customOptions = Array.from(customValues)
    .sort()
    .map((value) => ({ value, label: titleCaseToken(value) }));

  return [...BASE_EQUIPMENT_OPTIONS, ...customOptions];
}

export function deriveMuscleGroupOptions(exercises: Exercise[]): string[] {
  const baseValues = new Set(BASE_MUSCLE_GROUPS.map(normalizeValue));
  const customValues = new Set<string>();

  for (const exercise of exercises) {
    const groups = parseJsonArray(exercise.muscleGroups);
    for (const group of groups) {
      const value = normalizeValue(group);
      if (value && !baseValues.has(value)) {
        customValues.add(value);
      }
    }
  }

  return [...BASE_MUSCLE_GROUPS, ...Array.from(customValues).sort()];
}

export function deriveTrackingFieldOptions(exercises: Exercise[]): Option[] {
  const baseValues = new Set(BASE_TRACKING_FIELDS.map((item) => item.value));
  const customValues = new Set<string>();

  for (const exercise of exercises) {
    const fields = parseJsonArray((exercise as any).inputFields || "[]");
    for (const field of fields) {
      const value = normalizeValue(field);
      if (value && !baseValues.has(value)) {
        customValues.add(value);
      }
    }
  }

  const customOptions = Array.from(customValues)
    .sort()
    .map((value) => ({ value, label: titleCaseToken(value) }));

  return [...BASE_TRACKING_FIELDS, ...customOptions];
}

export function displayLabel(value: string): string {
  return titleCaseToken(value);
}
