import httpStatus from 'http-status';
import { Types } from 'mongoose';

import { Project } from '@/modules/project/project.model';
import {
  ITimelineDoc,
  NewCreatedTimeline,
  UpdateTimelineBody,
} from '@/modules/project/timeline/timeline.interface';
import { ApiError } from '@/shared/utils/errors';
import { Timeline } from './timeline.model';

export const createTimeline = async (
  timelineBody: NewCreatedTimeline,
): Promise<ITimelineDoc> => {
  const projectExists = await Project.exists({ _id: timelineBody.project });
  if (!projectExists)
    throw new ApiError(httpStatus.NOT_FOUND, 'Project not found');

  return Timeline.create(timelineBody);
};

export const getTimelineById = async (
  id: Types.ObjectId | string,
): Promise<ITimelineDoc> => {
  const timeline = await Timeline.findById(id);
  if (!timeline) throw new ApiError(httpStatus.NOT_FOUND, 'Timeline not found');

  return timeline;
};

export const updateTimeline = async (
  timelineId: Types.ObjectId | string,
  updateBody: UpdateTimelineBody,
): Promise<ITimelineDoc> => {
  const timeline = await getTimelineById(timelineId);

  if (updateBody.project) {
    const projectExists = await Project.exists({ _id: updateBody.project });
    if (!projectExists)
      throw new ApiError(httpStatus.NOT_FOUND, 'Project not found');
  }

  Object.assign(timeline, updateBody);
  await timeline.save();
  return timeline;
};

export const deleteTimeline = async (
  timelineId: Types.ObjectId | string,
): Promise<ITimelineDoc> => {
  const timeline = await getTimelineById(timelineId);
  await timeline.deleteOne();
  return timeline;
};
export const queryTimelines = async (
  filter: Record<string, string> = {},
  options = {},
) => {
  const queryFilter: Record<string, unknown> = { ...filter };

  if (queryFilter.year) {
    const year = parseInt(String(queryFilter.year), 10);

    const startOfYear = new Date(year, 0, 1);
    const endOfYear = new Date(year, 11, 31);

    queryFilter.startDate = { $lte: endOfYear };
    queryFilter.endDate = { $gte: startOfYear };

    delete queryFilter.year;
  }

  return Timeline.paginate(queryFilter, options);
};
