import { type InfiniteData, type QueryKey } from 'react-query';

import { type PaginatedResponse, type Pagination } from 'src/utils/tableUtils';

import {
  type LearningDuration,
  type LearningSegmentation,
  type SortingOrderType,
  type TableColumnsType,
} from '../common/types';

import {
  type CustomDueDatePeriod,
  type DueDateType,
  type PathStatus,
  PathSteps,
} from './constants';
import { type TSuccess } from './hooks/useGetPaths';

export type PathStepsType = (typeof PathSteps)[keyof typeof PathSteps];
export type PathStatusType = (typeof PathStatus)[keyof typeof PathStatus];
export type DueDateType = (typeof DueDateType)[keyof typeof DueDateType];
export type CustomDueDatePeriod =
  (typeof CustomDueDatePeriod)[keyof typeof CustomDueDatePeriod];

export type NewPathFormValues = {
  [PathSteps.BASIC_INFORMATION]: PathBasicInformation;
  [PathSteps.CONFIGURATION]: PathConfiguration;
  [PathSteps.CONTENT]: PathContent;
  [PathSteps.SEGMENTATION]: LearningSegmentation | null;
};

export type PathBasicInformation = {
  title: string;
  description: string | null;
  status: PathStatusType | null;
  id: number | null;
  coverPicture: PathCoverPicture | null;
};

export type PathConfiguration = {
  isObligatory: boolean;
  isSequential: boolean;
  sendPushNotification: boolean;
  sendEmailNotification: boolean;
  issueCertificate: boolean;
  dueDate: string | null;
};

type PathContent = {
  courses: PathCourse[];
};

type PathCoverPicture = {
  original: File | null;
  cropped: File | null;
  url: string | null;
};

export enum CourseInsertPosition {
  BEFORE = -1,
  AFTER = 1,
}

export type CreatePathPostType = Pick<
  CreateLearningPath,
  'title' | 'isSequential'
>;

export type PathCourse = {
  id: number;
  courseId: number;
  title: string;
  duration?: number;
  durationTime?: LearningDuration;
  coverImage?: string;
  categoryName?: string;
  createdAt?: string;
  updatedAt?: string;
  learningPathId?: number;
  position?: number;
};

export type PathDetail = {
  id: number;
  title: string;
  description: string | null;
  pictureUrl: string | null;
  isSequential: boolean;
  status: PathStatusType;
  instanceId: number;
  userId: number;
  createdAt: string;
  updatedAt: string;
  courses: PathCourse[];
  dueDate: PathDueDate | null;
  isObligatory: boolean;
  sendNotification: NotificationChannel | null;
  issueCertificate: boolean;
  participation: number;
};

export type CreateLearningPath = {
  title: string;
  description: string | null;
  pictureUrl: string | null;
  isSequential: boolean;
  isObligatory: boolean;
  issueCertificate: boolean;
  status: PathStatusType;
  courses: CreateLearningPathCourse[];
  dueDate: PathDueDate | null;
  sendNotification: NotificationChannel;
};

export const NotificationChannel = {
  PUSH: 'PUSH',
  EMAIL: 'EMAIL',
  PUSH_AND_EMAIL: 'PUSH_AND_EMAIL',
  NONE: 'NONE',
} as const;
export type NotificationChannel =
  (typeof NotificationChannel)[keyof typeof NotificationChannel];

export type Path = Pick<
  PathDetail,
  | 'description'
  | 'id'
  | 'participation'
  | 'status'
  | 'title'
  | 'updatedAt'
  | 'pictureUrl'
> & {
  courses: string[];
};

export type PathsStats = {
  totalCreatedPaths: number;
  totalEnrolledPathUsers: number;
  totalInProgressPathUsers: number;
  totalFinishedPathUsers: number;
};

export type PathDueDate = {
  dueDateType: DueDateType;
  customDueDatePeriod: CustomDueDatePeriod;
  customDueDateAmount: number;
};

export type PathsResponse = {
  learningPaths: PaginatedResponse<Path>;
  stats: PathsStats;
};

export type PathsPagination = Partial<Pagination> & {
  status: PathStatusType | undefined;
  orderBy: TableColumnsType;
  order: SortingOrderType;
};

export type CreateLearningPathCourse = {
  courseId: number;
  position: number;
};

export type ShowAdminInformation = {
  showAdminInformation: boolean;
};

export type PreviousPathsDataContext = {
  previousPathsQueries: [QueryKey, InfiniteData<TSuccess> | undefined][];
  previousDetail: Path | undefined;
};
