import { prisma } from "../prisma";
import { Prisma, Workout } from "@prisma/client";
import { SearchFilters } from "@/types";

/**
 * Get all workouts for a user with optional filters
 */
export async function getWorkouts(
  userId: string,
  filters?: SearchFilters
) {
  const {
    query,
    exerciseId,
    dateFrom,
    dateTo,
    limit = 50,
    offset = 0,
  } = filters || {};

  const where: Prisma.WorkoutWhereInput = {
    userId,
    deletedAt: null,
  };

  if (query) {
    where.name = { contains: query };
  }

  if (dateFrom || dateTo) {
    const dateFilter: Prisma.DateTimeFilter = {};
    if (dateFrom) dateFilter.gte = dateFrom;
    if (dateTo) dateFilter.lte = dateTo;
    where.date = dateFilter;
  }

  const workouts = await prisma.workout.findMany({
    where,
    include: {
      setLogs: {
        include: {
          exercise: true,
        },
        orderBy: {
          setNumber: "asc",
        },
      },
    },
    orderBy: {
      date: "desc",
    },
    take: limit,
    skip: offset,
  });

  // Filter by exerciseId if provided
  if (exerciseId) {
    return workouts.filter((workout) =>
      workout.setLogs.some((set) => set.exerciseId === exerciseId)
    );
  }

  return workouts;
}

/**
 * Get a single workout by ID with all its sets
 */
export async function getWorkoutById(id: string) {
  return prisma.workout.findFirst({
    where: { id, deletedAt: null },
    include: {
      setLogs: {
        include: {
          exercise: true,
        },
        orderBy: {
          setNumber: "asc",
        },
      },
    },
  });
}

/**
 * Create a new workout
 */
export async function createWorkout(data: {
  userId: string;
  name: string;
  date?: Date;
  notes?: string;
  duration?: number;
}): Promise<Workout> {
  return prisma.workout.create({
    data: {
      userId: data.userId,
      name: data.name,
      date: data.date || new Date(),
      notes: data.notes,
      durationMinutes: data.duration,
    },
  });
}

/**
 * Delete a workout and all its associated sets
 */
export async function deleteWorkout(id: string): Promise<void> {
  await prisma.workout.update({
    where: { id },
    data: { deletedAt: new Date() },
  });
}

/**
 * Get recent workouts for a user
 */
export async function getRecentWorkouts(
  userId: string,
  limit: number = 10
) {
  return prisma.workout.findMany({
    where: { userId, deletedAt: null },
    include: {
      setLogs: {
        include: {
          exercise: true,
        },
        orderBy: {
          setNumber: "asc",
        },
      },
    },
    orderBy: {
      date: "desc",
    },
    take: limit,
  });
}

/**
 * Search workouts by name, date range, or exercise
 */
export async function searchWorkouts(
  userId: string,
  query: string,
  dateFrom?: Date,
  dateTo?: Date
) {
  return getWorkouts(userId, {
    query,
    dateFrom,
    dateTo,
    limit: 100,
  });
}
