import { type FileAsset } from '@material-hu/types/attachments';

import { type FileCardType } from '@material-hu/components/design-system/FileCard/types';

import { type Attachment } from 'src/types/attachments';
import { type IconInterface } from 'src/types/icons';
import { type QuestionType } from 'src/types/surveys';
import { type User, type UserStatus } from 'src/types/user';
import { type Pagination } from 'src/utils/tableUtils';

import { type FormDropValue } from 'src/components/FormInputs/FormDropAttachments/types';
import { type Option } from 'src/components/FormInputs/FormOptions/types';

import { type LearningDuration } from '../common/types';
import { type Path } from '../Paths/types';
import {
  type Category,
  type CategoryAutocompleteOption,
} from '../Settings/Categories/types';

export enum CreateQuestionModes {
  CREATE = 'create',
  EDIT = 'edit',
  DUPLICATE = 'duplicate',
}

export type DownloadReportFnParams = {
  email: string;
  includeGroups: number[];
  includeUserFields: string[];
};

export enum DraftStatus {
  EMPTY = 'EMPTY',
  SAVED = 'SAVED',
  HAS_CHANGES = 'HAS_CHANGES',
}

export type GetColabsParams = Pagination & {
  status?: string; // comma separated list of (ColabStatus) values
};

export type OnDraftProps = {
  values: StepsTypes;
  deletedModules: number[];
  deletedTasks: number[];
  currentStep: Steps;
};

export enum ReportSentTypes {
  DOWNLOAD = 'download',
  EMAIL = 'email',
}

export type CourseOnPathResponse = {
  hasLearningPaths: boolean;
  learningPaths: Pick<Path, 'id' | 'title'>[];
};

export type DownloadReportParams = {
  courseId: number;
  email: string;
  isAttendanceReport: boolean;
  includeGroups: number[];
  includeUserFields: string[];
};

export enum NotificationOptions {
  PUSH = 'push',
  NONE = 'none',
}

export const CourseNotificationChannel = {
  PUSH: 'PUSH',
  EMAIL: 'EMAIL',
  PUSH_AND_EMAIL: 'PUSH_AND_EMAIL',
  NONE: 'NONE',
} as const;

export type CourseNotificationChannel =
  (typeof CourseNotificationChannel)[keyof typeof CourseNotificationChannel];

export enum NotificationTypes {
  CREATE = 'create',
  EDIT = 'edit',
  ACTIVATE = 'activate',
  PENDING = 'pending',
  DUPLICATE = 'duplicate',
}

export enum CourseFunnels {
  EDIT = 'edition',
  CREATE = 'creation',
  DUPLICATE = 'duplication',
}

export enum AudienceTypes {
  ALL = 'all',
  SEGMENTS = 'segments',
}

export enum ReportTypes {
  COLABS = 'colabs',
  ATTENDANCE = 'attendance',
  EVALUATIONS = 'evaluations',
  SURVEYS = 'surveys',
}

export const DownloadReportOptions = {
  ATTENDANCE: 'attendance',
  GENERAL: 'general',
  BULK_CERTIFICATES: 'bulk_certificates',
} as const;

export type DownloadReportType =
  (typeof DownloadReportOptions)[keyof typeof DownloadReportOptions];

export enum ColabStatus {
  PENDING_SIGNATURE = 'PENDING_SIGNATURE',
  PENDING = 'PENDING',
  EXPIRED = 'EXPIRED',
  IN_PROGRESS = 'IN_PROGRESS',
  FINISHED = 'FINISHED',
}

export enum Steps {
  BASIC_INFORMATION = 'basicInformation',
  CONFIGURATION = 'configuration',
  CONTENT = 'content',
  FINAL_REVISION = 'finalRevision',
}

export enum CourseTypes {
  REQUIRED = 'required',
  OPTIONAL = 'optional',
}

export enum DeadlineTypes {
  FROM_ASSIGNMENT = 'CUSTOM',
  NO_DEADLINE = 'NO_DUE_DATE',
}

export enum SegmentationOption {
  ALL = 'ALL',
  SEGMENTED = 'SEGMENTED',
}

export enum TaskTypes {
  NEW = 'NEW',
  TASK = 'TASK',
  VIDEO = 'VIDEO',
  READING = 'READING',
  QUESTIONNAIRE = 'EVALUATION',
  BLANK = 'LESSON',
  SCORM = 'SCORM',
}

export enum ReadingTypes {
  MANUAL = 'MANUAL',
  PDF = 'PDF',
}

export enum QuestionSubheaders {
  GENERAL = 'GENERAL',
  SELECTION = 'SELECTION',
}

export enum VideoTypes {
  EXTERNAL = 'EXTERNAL',
  INTERNAL = 'INTERNAL',
}

export enum CourseStatus {
  ACTIVE = 'ACTIVE',
  INACTIVE = 'INACTIVE',
  DRAFT = 'DRAFT',
}

export enum DeadlinePeriods {
  DAYS = 'DAYS',
  WEEKS = 'WEEKS',
  MONTHS = 'MONTHS',
}

export type Selected = {
  module: number;
  task: number;
};

export type PartialTask = {
  id: number | string;
  tag?: string;
  title: string;
  type: TaskTypes;
  description?: string;
  drops?: FormDropValue[];
};

export type FormatTask<T> = PartialTask & T;

export type LessonTask = FormatTask<{
  body: string;
}>;

export type VideoTask = FormatTask<{
  video: {
    url?: string;
    file?: File;
  };
  urlType: VideoTypes;
}>;

export type ReadingTask = FormatTask<{
  reading: {
    type: ReadingTypes;
    pdf?: {
      url?: string;
      file?: File;
    };
    body?: string;
  };
}>;

export type ScormTask = FormatTask<{
  scorm: {
    zip: {
      url?: string;
      file?: File;
    };
  };
}>;

export type EvaluationTask = FormatTask<{
  maximumAttempts: number;
  passingGrade: number;
  duration: number;
  showCorrectAnswers: boolean;
  form: {
    id: number | string;
    tag?: string;
    title?: string;
    description?: string;
    questions: Question[];
  };
}>;

export type Question = {
  id: string;
  title: string;
  description?: string;
  explanation?: string;
  type: QuestionType;
  choices?: Option[];
  hasExplanation: boolean;
  attachments?: FileAsset[];
  points: number;
};

export type QuestionFormValues = Omit<Question, 'attachments'> & {
  attachments?: FileCardType[];
};

export type Task =
  | LessonTask
  | VideoTask
  | ReadingTask
  | EvaluationTask
  | ScormTask;

export type Module = {
  id: number | string;
  title: string;
  icon: IconInterface;
  tasks: Task[];
};

export type StepsTypes = {
  basicInformation: {
    title: string;
    body?: string;
    image?: { cropped: File; original: File; url?: string | null };
    status: CourseStatus;
    duration?: string;
    category?: CategoryAutocompleteOption | null;
    isCourseStarted: boolean;
  };
  content: {
    modules: Module[];
  };
  configuration: {
    type: CourseTypes;
    sequentiality: boolean;
    deadline: boolean;
    deadlineType?: DeadlineTypes;
    deadlineDays?: string;
    segmentation?: {
      groupSegmentation: number[];
      userSegmentation: Pick<User, 'id' | 'firstName' | 'lastName'>[];
    };
    sendPushNotification: boolean;
    sendEmailNotification: boolean;
    hasSurvey: boolean;
    issueCertificate: boolean;
    digitalSignature: boolean;
    refreshFinishedCourseUsers: boolean;
    instructor: string;
  };
};

export type AudienceValues = {
  values: StepsTypes;
  courseId: Course['id'];
};

export type UpdateDraftValues = {
  values: StepsTypes;
  courseId: Course['id'];
  deletedModules: number[];
  deletedTasks: number[];
};

export type Course = {
  id: number;
  title: string;
  status: CourseStatus;
  updatedAt: string;
  createdAt: string;
  creatorId: number;
  creatorName: string;
};

export type SegmentationIds = {
  segmentationUserIds: number[] | null;
  segmentationItemIds: number[] | null;
};

export enum CourseCategorySortingOrder {
  NAME_ASC = 'NAME_ASC',
  NAME_DESC = 'NAME_DESC',
}

export type CourseListItem = {
  id: number;
  title: string;
  status: CourseStatus;
  category: Category;
  courseCategoryId: number;
  updatedAt: string;
  digitalSignature: boolean;
  creatorId: number;
  coverImage?: string;
  duration?: number;
  durationTime?: LearningDuration;
  creatorName: string;
  totalAssigned: number;
  totalFinished: number;
};

export type CreateCourseCategoryParams = {
  name: string;
  parentId?: number;
};

export type QuestionDetail = CreateQuestionData & {
  id: number;
};

export type CourseDetail = Omit<
  CreateCourseData,
  'modules' | 'durationHours' | 'durationMinutes'
> & {
  id: number;
  isCourseStarted: boolean;
  category: Category;
  modules: ModuleDetail[];
  durationTime: LearningDuration;
};

export type ModuleDetail = Omit<CreateModuleData, 'tasks'> & {
  id: number;
  tasks: TaskDetail[];
};

export type TaskDetail = CreateTaskData & {
  id: number;
};

export type ColabsMetrics = {
  averageProgress: number;
  totalEnrolledCourseUsers: number;
  totalInProgressCourseUsers: number;
  totalFinishedCourseUsers: number;
};

export type ColabListItem = {
  name: string;
  courseUserStatus: ColabStatus;
  userStatus: UserStatus;
  isExpired: boolean;
  startedAt: Date;
  finishedAt: Date | null;
  userId: number;
  daysPassed: number;
  progress: number;
  totalEvaluations: number;
  totalEvaluationsDone: number;
  averageGrade: number | null;
  passed: boolean | null;
};

export enum SurveyQuestions {
  EXPERIENCE_RATING = 'EXPERIENCE_RATING',
  CONTENT_RATING = 'CONTENT_RATING',
  RECOMMENDATION = 'RECOMMENDATION',
}

export type SurveyQuestion = {
  questionId: string;
  answer: string;
  score: number;
  title: string;
};

export type SurveysMetrics = {
  totalFinished: number;
  totalSurveyCompleted: number;
  questionAnswers: SurveyQuestion[];
};

export type SurveyListItem = {
  comment: string;
};

export type EvaluationListItem = {
  tag: string;
  title: string;
  approvedUsers: number;
  averageGrade: string;
  disapprovedUsers: number;
  lastModificationDate: string;
  passingGrade: number;
  moduleTitle: string;
  questionAmount: number;
};

// Data
export type PartialCreateTaskData = {
  position: number;
  hasNewChanges?: boolean;
  attachments?: Attachment[];
};

export type FormatCreateTaskData<T> = PartialCreateTaskData & Omit<T, 'drop'>;

export type CreateLessonTaskData = FormatCreateTaskData<LessonTask>;

export type CreateVideoTaskData = FormatCreateTaskData<
  Omit<VideoTask, 'video'> & {
    url: string;
  }
>;

export type CreateReadingTaskData = FormatCreateTaskData<
  Omit<ReadingTask, 'reading'> & {
    url?: string;
    body?: string;
  }
>;

export type CreateEvaluationTaskData = FormatCreateTaskData<
  Omit<EvaluationTask, 'form'> & {
    form: {
      id?: number;
      tag?: string;
      title?: string;
      description?: string;
      questions: CreateQuestionData[];
    };
  }
>;

export type CreateScormTaskData = FormatCreateTaskData<
  Omit<ScormTask, 'scorm'> & {
    url: string;
  }
>;

export type CreateTaskData =
  | CreateLessonTaskData
  | CreateVideoTaskData
  | CreateReadingTaskData
  | CreateEvaluationTaskData
  | CreateScormTaskData;

export type CreateModuleData = {
  id?: number;
  title: string;
  icon: Omit<IconInterface, 'custom'>;
  position: number;
  tasks?: CreateTaskData[];
};

export type CreateCourseData = {
  title: string;
  body?: string;
  pictureUrl?: string | null;
  durationHours?: number | null;
  durationMinutes?: number | null;
  courseCategoryId?: number | null;
  isObligatory: boolean;
  status: CourseStatus;
  dueDate: {
    dueDateType: DeadlineTypes;
    customDueDateAmount?: number;
    customDueDatePeriod?: DeadlinePeriods;
  };
  isSequential: boolean;
  modules: CreateModuleData[];
  hasSurvey: boolean;
  sendNotification: CourseNotificationChannel;
  issueCertificate: boolean;
  digitalSignature: boolean;
  refreshFinishedCourseUsers: boolean;
  instructor?: string | null;
};

export type UpdateCourseData = Partial<CreateCourseData>;

export type CreateDraftData = Pick<
  CreateCourseData,
  'title' | 'body' | 'pictureUrl' | 'durationHours' | 'durationMinutes'
>;

export type CreateQuestionData = Omit<
  Question,
  'choices' | 'hasExplanation'
> & {
  choices: string[];
  correctAnswers: string[];
};

export type EditCourseAudienceData = SegmentationIds & {
  sendNotification: boolean;
};

export type EditCourseStatusData = {
  status: CourseStatus;
  sendNotification: boolean;
};

export type CoursesMetrics = {
  totalCreatedCourses: number;
  totalEnrolledCourseUsers: number;
  totalInProgressCourseUsers: number;
  totalFinishedCourseUsers: number;
};

export enum DroppableType {
  MODULE = 'MODULE',
  TASK = 'TASK',
}

export type GetEvaluationReportData = {
  tag: string;
  groupIds: any[];
  userFields: any[];
  email?: string;
};

export type CoursesListParams = Pagination &
  CategoryFilter & {
    sortingOption: string | undefined;
  };

export type CategoryFilter = {
  categoryIds: string;
  includeNoCategory: boolean;
};

export enum NoCategory {
  ID = '-1',
}

export type CategoriesRecord = Record<string, boolean>;
