import api from 'src/config/api';
import {
  type CalibratedUser,
  type CalibrationReview,
  type CalibrationReviewDetail,
  type ExternalUserReviewer,
  type FillCalibrationBody,
  type LeaderDashboardFilter,
  type PerformanceNotificationsResponse,
  type ReviewBody,
  type ReviewDetail,
  ReviewDirection,
  type ReviewedUserSelection,
  type ReviewerUserSelection,
  type ReviewProgressStats,
  type ReviewRole,
  type ReviewUser,
  type ReviewUserToShare,
} from 'src/pages/dashboard/performance/types';
import { type Pagination } from 'src/types/services';
import { formatPagination, type PaginationParams } from 'src/utils/pagination';

export const getReviewsCycles = (params: Record<string, unknown>) =>
  api.get('performance-reviews', { params });

export const getReviewCycle = (id: string | number) =>
  api.get(`performance-reviews/${id}`);

export const getReviewDetail = (cycleId: string, reviewId: number) =>
  api.get<ReviewDetail>(`performance-reviews/${cycleId}/reviews/${reviewId}`);

export const completeReview = (
  cycleId: string,
  reviewId: number,
  body: ReviewBody,
) => api.post(`performance-reviews/${cycleId}/reviews/${reviewId}`, body);

export const editReview = (
  cycleId: string,
  reviewId: number,
  body: ReviewBody,
) => api.put(`performance-reviews/${cycleId}/reviews/${reviewId}`, body);

export const shareReview = (
  cycleId: string,
  userId: number,
  summary?: string,
) =>
  api.post(`performance-reviews/${cycleId}/target-users/${userId}/share`, {
    summary,
  });

export const saveSummary = (cycleId: string, userId: number, summary: string) =>
  api.patch(`performance-reviews/${cycleId}/target-users/${userId}`, {
    summary,
  });

export const requestReviewEdition = (
  cycleId: string,
  reviewId: number,
  description?: string,
) =>
  api.post(`performance-reviews/${cycleId}/reviews/${reviewId}/edit-requests`, {
    description,
  });

export const confirmReception = (cycleId: string, userId: number) =>
  api.post(`performance-reviews/${cycleId}/target-users/${userId}/confirm`);

export const getReviewStats = (id: number, responsibleId: number | undefined) =>
  api.get<ReviewProgressStats>(`performance-reviews/${id}/reviews/stats`, {
    params: { responsibleId },
  });

export const getReviewUsers = (
  id: string | undefined,
  role: ReviewRole,
  responsibleId: number | undefined,
  pagination: LeaderDashboardFilter & {
    page: number;
    limit: number;
    order?: string;
    orderBy?: string;
  },
) => {
  const { q, pendingActionFilter, teamScore, sortBy, sortDirection, ...rest } =
    pagination;
  const paginationParams: PaginationParams = rest;
  return api.get<Pagination<ReviewUser[]>>(
    `performance-reviews/${id}/review-users`,
    {
      params: {
        role,
        responsibleId,
        ...(q ? { q } : {}),
        ...(pendingActionFilter !== undefined ? { pendingActionFilter } : {}),
        ...(teamScore !== undefined ? { teamScore } : {}),
        ...(sortBy !== undefined ? { sortBy } : {}),
        ...(sortDirection !== undefined ? { sortDirection } : {}),
        ...formatPagination(paginationParams),
      },
    },
  );
};

export const getUsersToShare = (
  id: number,
  responsibleId: number,
  pagination: PaginationParams,
) =>
  api.get<Pagination<Omit<ReviewUserToShare, 'reviewedFormReviews'>[]>>(
    `performance-reviews/${id}/target-users`,
    {
      params: {
        responsibleId,
        ...pagination,
      },
    },
  );

export const getUserToShare = (id: number, userId: number) =>
  api.get<ReviewUserToShare>(
    `performance-reviews/${id}/target-users/${userId}`,
  );

export const getPeerRevieweds = (id: string, pagination: PaginationParams) =>
  api.get<Pagination<ReviewedUserSelection[]>>(
    `performance-reviews/${id}/revieweds`,
    {
      params: {
        ...formatPagination(pagination),
      },
    },
  );

export const getPeerReviewersSelected = (
  id: string,
  reviewedId: number,
  evaluationType: ReviewDirection,
) =>
  api.get<ReviewerUserSelection[]>(
    `performance-reviews/${id}/target-users/${reviewedId}/reviewers`,
    {
      params: {
        evaluationType,
      },
    },
  );

export const updatePeerReviewersSelected = ({
  cycleId,
  userId,
  evaluationType,
  reviewerIdsToAdd,
  reviewerIdsToDelete,
}: {
  cycleId: number;
  userId: number;
  evaluationType: ReviewDirection;
  reviewerIdsToAdd: number[] | undefined;
  reviewerIdsToDelete: number[] | undefined;
}) => {
  const isExternal = evaluationType === ReviewDirection.PEER_EXTERNAL_REVIEW;
  const isOthers = evaluationType === ReviewDirection.OTHERS_REVIEW;
  const isPeer = evaluationType === ReviewDirection.PEER_REVIEW;

  return api.patch(
    `performance-reviews/${cycleId}/target-users/${userId}/reviewers`,
    {
      reviewerIdsToAdd: isPeer ? reviewerIdsToAdd : undefined,
      reviewerIdsToDelete: isPeer ? reviewerIdsToDelete : undefined,
      externalReviewerIdsToAdd: isExternal ? reviewerIdsToAdd : undefined,
      externalReviewerIdsToDelete: isExternal ? reviewerIdsToDelete : undefined,
      othersReviewerIdsToAdd: isOthers ? reviewerIdsToAdd : undefined,
      othersReviewerIdsToDelete: isOthers ? reviewerIdsToDelete : undefined,
    },
  );
};

export const getExternalUserReviewers = (pagination: PaginationParams) =>
  api.get<Pagination<ExternalUserReviewer[]>>(
    'performance-reviews/external-reviewers',
    {
      params: {
        ...formatPagination(pagination),
      },
    },
  );

export const createExternalUserReviewers = ({
  firstName,
  lastName,
  email,
}: {
  firstName: string;
  lastName: string;
  email: string;
}) =>
  api.post('performance-reviews/external-reviewers', {
    firstName,
    lastName,
    email,
  });

export const getExternalCycle = (
  cycleId: string,
  externalReviewerId: number | null,
) =>
  api.get(`performance-reviews/external-reviewers/${cycleId}`, {
    params: {
      externalReviewerId,
    },
  });

export const getExternalReview = (
  cycleId: string,
  reviewId: number,
  externalReviewerId: number | null,
) =>
  api.get<ReviewDetail>(
    `performance-reviews/external-reviewers/${cycleId}/reviews/${reviewId}`,
    {
      params: {
        externalReviewerId,
      },
    },
  );

export const completeExternalReview = (
  cycleId: string,
  reviewId: number,
  externalReviewerId: number | null,
  body: ReviewBody,
) =>
  api.post(
    `performance-reviews/external-reviewers/${cycleId}/reviews/${reviewId}?externalReviewerId=${externalReviewerId}`,
    body,
  );

export const getPerformanceNotifications = () =>
  api.get<PerformanceNotificationsResponse>('red-bubbles/performance-reviews');

export const getCalibrations = (
  cycleId: string | number,
  pagination: PaginationParams & { q?: string; answered?: boolean },
) => {
  const { q, answered, ...rest } = pagination;
  return api.get<Pagination<CalibratedUser[]>>(
    `performance-reviews/${cycleId}/calibrations`,
    {
      params: {
        ...(q ? { q } : {}),
        ...(answered !== undefined ? { answered } : {}),
        ...formatPagination(rest),
      },
    },
  );
};

export const getCalibrationDetail = (
  cycleId: string | number,
  formReviewId: string | number,
) =>
  api.get<CalibrationReviewDetail>(
    `performance-reviews/${cycleId}/calibrations/${formReviewId}`,
  );

export const fillCalibration = (
  cycleId: string | number,
  formReviewId: string | number,
  body: FillCalibrationBody,
) =>
  api.post<CalibrationReview>(
    `performance-reviews/${cycleId}/calibrations/${formReviewId}/fill`,
    body,
  );
