import { useEffect, useState } from 'react';
import { useFieldArray, useFormContext } from 'react-hook-form';

import Stack from '@material-hu/mui/Stack';

import ContentEmpty from 'src/pages/dashboard/Learning/Courses/New/components/ContentEmpty';
import ContentModule from 'src/pages/dashboard/Learning/Courses/New/components/ContentModule';
import ContentSidebar from 'src/pages/dashboard/Learning/Courses/New/components/ContentSidebar';
import ContentTask from 'src/pages/dashboard/Learning/Courses/New/components/ContentTask';
import {
  getInternalId,
  MODULE_DEFAULT_ICON,
  STEPPER_HEIGHT,
} from 'src/pages/dashboard/Learning/Courses/New/constants';
import { newCourseFields } from 'src/pages/dashboard/Learning/Courses/New/forms';
import {
  getModuleElementId,
  getTaskElementId,
} from 'src/pages/dashboard/Learning/Courses/New/utils';
import {
  type Selected,
  type Task,
  TaskTypes,
} from 'src/pages/dashboard/Learning/Courses/types';
import { addOrRemove } from 'src/utils/arrayUtils';
import { useLokaliseTranslation } from 'src/utils/i18n';

export type ContentProps = {
  disabled?: boolean;
  showInfoAlert?: boolean;
  onCloseInfoAlert?: () => void;
  onCreateModule?: () => void;
  onDeleteModule?: (module: number) => void;
  onCreateTask?: () => void;
  onDeleteTask?: (module: number, task: number) => void;
  onSelectTaskType?: () => void;
  onCancelTaskType?: () => void;
  onSelected?: (selected: Selected) => void;
  moduleCount: number;
  taskCount: number;
  showValidation?: boolean;
};

export const Content = ({
  disabled = false,
  showInfoAlert = false,
  onCloseInfoAlert = () => null,
  onCreateModule = () => null,
  onDeleteModule = () => null,
  onCreateTask = () => null,
  onDeleteTask = () => null,
  onSelectTaskType = () => null,
  onCancelTaskType = () => null,
  onSelected = () => null,
  moduleCount,
  taskCount,
  showValidation = false,
}: ContentProps) => {
  const { t } = useLokaliseTranslation('learning');

  const modulesName = newCourseFields.content.modules.all();

  const { control, getValues, setValue } = useFormContext();

  const modules = useFieldArray({
    control,
    name: modulesName,
  });

  const getLast = (module: number = -1) => {
    const newList =
      module < 0
        ? getValues(modulesName)
        : getValues(newCourseFields.content.modules.tasks.all(module));

    return {
      last: newList[newList.length - 1],
      index: newList.length - 1,
    };
  };

  const [selected, setSelected] = useState<Selected>({
    module: getLast().index,
    task: -1,
  });
  const [expanded, setExpanded] = useState<number[]>(
    getLast().last ? [getLast().last.id] : [],
  );

  useEffect(() => {
    onSelected(selected);
  }, [selected]);

  useEffect(() => {
    if (selected.module >= 0) {
      const elementId =
        selected.task >= 0
          ? getTaskElementId(selected.module, selected.task)
          : getModuleElementId(selected.module);

      const lastElement = document.getElementById(elementId);
      lastElement?.scrollIntoView({ behavior: 'smooth', block: 'center' });
    }
  }, [selected]);

  const handleExpand = (moduleExpanded: number) =>
    setExpanded(addOrRemove(expanded, moduleExpanded));

  const handleSelect = (newSelected: Selected) => {
    setSelected(newSelected);
    const moduleIdToExpand = getValues(modulesName)[newSelected.module]?.id;
    if (!expanded.includes(moduleIdToExpand)) {
      handleExpand(moduleIdToExpand);
    }
  };

  const handleCreateModule = () => {
    modules.append({
      id: getInternalId(moduleCount + 1),
      title: t('common.module_empty'),
      icon: MODULE_DEFAULT_ICON,
      tasks: [],
    });
    handleSelect({ module: getLast().index, task: -1 });
    onCreateModule();
  };

  const handleDeleteModule = (moduleDeleted: number) => {
    onDeleteModule(moduleDeleted);

    const newModules = [...getValues(modulesName)];
    const [deleted] = newModules.splice(moduleDeleted, 1);
    modules.replace(newModules);

    setExpanded(expanded.filter(id => id !== deleted.id));

    if (selected.module === moduleDeleted) {
      handleSelect({ module: getLast().index, task: -1 });
    } else if (selected.module > moduleDeleted) {
      handleSelect({ module: selected.module - 1, task: -1 });
    }
  };

  const handleCreateTask = (module: number) => {
    const tasksName = newCourseFields.content.modules.tasks.all(module);

    const newTasks = [...getValues(tasksName)];
    newTasks.push({
      id: getInternalId(taskCount + 1),
      title: t('course.lesson.title_placeholder'),
      type: TaskTypes.NEW,
      attachments: [],
    });

    setValue(tasksName, newTasks);

    const newModules = getValues(modulesName);

    if (newModules[module] && !expanded.includes(newModules[module].id)) {
      handleExpand(newModules[module].id);
    }

    handleSelect({
      module,
      task: getLast(module).index,
    });

    onCreateTask();
  };

  const handleDeleteTask = (module: number, task: number) => {
    onDeleteTask(module, task);

    const tasksName = newCourseFields.content.modules.tasks.all(module);

    const newTasks = [...getValues(tasksName)];
    newTasks.splice(task, 1);

    setValue(tasksName, newTasks);

    if (selected.task === task) {
      handleSelect({ module, task: getLast(module).index });
    } else if (selected.task > task) {
      handleSelect({ module, task: selected.task - 1 });
    }
  };

  const handleSaveTask = () => {
    handleSelect({ module: selected.module, task: -1 });
  };

  const handleCancelTask = (task: Task) => {
    const taskName = newCourseFields.content.modules.tasks.detail(
      selected.module,
      selected.task,
    );

    setValue(taskName, {
      id: task.id,
      title: task.title || t('course.lesson.title_placeholder'),
      type: TaskTypes.NEW,
    });

    onCancelTaskType();
  };

  return (
    <Stack
      sx={{
        flexDirection: 'row',
        height: `calc(100% - ${STEPPER_HEIGHT})`,
      }}
    >
      <ContentSidebar
        name={modulesName}
        onSelect={handleSelect}
        selected={selected}
        onExpanded={handleExpand}
        expanded={expanded}
        onCreateModule={handleCreateModule}
        onDeleteModule={handleDeleteModule}
        onCreateTask={handleCreateTask}
        onDeleteTask={handleDeleteTask}
        showValidation={showValidation}
      />
      {selected.module < 0 && (
        <ContentEmpty
          disabled={disabled}
          onCreateModule={handleCreateModule}
        />
      )}
      {selected.module >= 0 && selected.task < 0 && (
        <ContentModule
          disabled={disabled}
          selected={selected}
          showInfoAlert={showInfoAlert}
          onCloseInfoAlert={onCloseInfoAlert}
          onCreateTask={handleCreateTask}
          onSelect={handleSelect}
        />
      )}
      {selected.module >= 0 && selected.task >= 0 && (
        <ContentTask
          disabled={disabled}
          selected={selected}
          onSave={handleSaveTask}
          onCancel={handleCancelTask}
          onSelectType={onSelectTaskType}
        />
      )}
    </Stack>
  );
};

export default Content;
