import { signedUploadV2 } from 'src/utils/filesUtils';
import { urlToFile } from 'src/utils/stringUtils';

import { type LearningAudience } from '../../common/types';
import { formatLearningAudience } from '../../common/utils';
import {
  CustomDueDatePeriod,
  DueDateType,
  PATH_NEW_DEFAULT_VALUES,
} from '../constants';
import {
  type CreateLearningPath,
  type NewPathFormValues,
  NotificationChannel,
  type PathDetail,
  type PathDueDate,
} from '../types';
import { fromNotificationChannel, toNotificationChannel } from '../utils';

export const formatBasicInformationData = async (
  formValues: NewPathFormValues,
): Promise<Partial<CreateLearningPath>> => {
  const { coverPicture } = formValues.basic_information;
  const isCreatingDraft = formValues.basic_information.id === null;
  const hasCoverPicture = Boolean(coverPicture?.url);

  let pictureUrl: string | null = null;

  if (!hasCoverPicture && coverPicture?.cropped) {
    const extension = coverPicture.cropped.type.split('/')[1];
    const newFileName = `${crypto.randomUUID()}.${extension}`;

    const pictureToUpload = new File([coverPicture.cropped], newFileName, {
      type: coverPicture.cropped.type,
    });

    pictureUrl = (await signedUploadV2(pictureToUpload)).url;
  }

  const response: Partial<CreateLearningPath> = {
    pictureUrl,
    title: formValues.basic_information.title,
    description: formValues.basic_information.description,
  };

  if (isCreatingDraft) {
    response.isSequential = false;
    response.sendNotification = NotificationChannel.PUSH;
    response.isObligatory = true;
  }

  return response;
};

export const formatPathContent = (
  values: NewPathFormValues,
): Partial<CreateLearningPath> => {
  const { content } = values;

  if (!content.courses.length) return { courses: [] };

  return {
    courses: content.courses.map(({ courseId }, courseIndex) => ({
      courseId,
      position: courseIndex + 1,
    })),
  };
};

export const formatPathConfiguration = (
  values: NewPathFormValues,
): Partial<CreateLearningPath> => {
  const { configuration } = values;

  const dueDate = {
    dueDateType: DueDateType.CUSTOM,
    customDueDatePeriod: CustomDueDatePeriod.DAYS,
    customDueDateAmount: Number(configuration.dueDate || 0),
  };

  const { sendPushNotification, sendEmailNotification, ...configurationRest } =
    configuration;

  return {
    ...configurationRest,
    dueDate,
    sendNotification: toNotificationChannel(
      sendPushNotification,
      sendEmailNotification,
    ),
  };
};

const formatPathDueDate = (dueDate: PathDueDate | null) => {
  if (!dueDate || dueDate.customDueDateAmount === 0) return null;
  return dueDate.customDueDateAmount.toString();
};

export const formatDefaultPathValues = async (
  path: PathDetail | undefined,
  audience: LearningAudience | undefined,
): Promise<NewPathFormValues> => {
  if (!path) return PATH_NEW_DEFAULT_VALUES;

  const pictureFile = path.pictureUrl ? await urlToFile(path.pictureUrl) : null;

  const orderedCourses = path.courses.sort(
    (a, b) => (a.position || 0) - (b.position || 0),
  );

  return {
    basic_information: {
      status: path.status,
      id: path.id,
      title: path.title,
      description: path.description,
      coverPicture: {
        original: pictureFile,
        cropped: pictureFile,
        url: path.pictureUrl,
      },
    },
    content: { courses: orderedCourses },
    configuration: {
      isObligatory: path.isObligatory,
      isSequential: path.isSequential,
      issueCertificate: path.issueCertificate,
      ...fromNotificationChannel(path.sendNotification),
      dueDate: formatPathDueDate(path.dueDate),
    },
    segmentation: formatLearningAudience(audience),
  };
};
