import { isEqual } from 'lodash-es';

import { type Option } from '@material-hu/components/composed-components/RadioGroup/types';
import { type DateRange } from '@material-hu/components/design-system/Inputs/Base/CustomRangeDatePicker/types';

import { type TimeSlot } from 'src/types/timeTracking';

import { COLOR_OPTIONS } from './constants';

export type ShiftTimeSlot = {
  id: number;
  startTime: Date | null;
  endTime: Date | null;
};

export type CollaboratorOption = {
  value: number;
  label: string;
  userInfo: {
    id: number;
    fullName: string;
    profilePicture?: string | null;
    employeeInternalId?: string;
  };
};

export type PreFillData = {
  collaborators?: CollaboratorOption[];
  date?: Date | null;
};

export type ShiftFormData = {
  collaborators: Option[];
  shiftName: string;
  color: string; // HEX value
  date: Date | null;
  timeSlots: ShiftTimeSlot[];
  repeat: string;
  notes: string;
};

export const CUSTOM_SHIFT_INITIAL_VALUES = {
  collaborators: [],
  shiftName: '',
  color: COLOR_OPTIONS[0].value,
  date: null,
  timeSlots: [
    {
      id: Date.now(),
      startTime: null,
      endTime: null,
    },
  ],
  repeat: 'none',
  notes: '',
};

export const shiftFormFields = {
  collaborators: 'collaborators',
  shiftName: 'shiftName',
  color: 'color',
  date: 'date',
  timeSlots: {
    base: 'timeSlots',
    slot: (slotIndex: number) => `timeSlots.${slotIndex}` as const,
    start: (slotIndex: number) => `timeSlots.${slotIndex}.startTime` as const,
    end: (slotIndex: number) => `timeSlots.${slotIndex}.endTime` as const,
  },
  repeat: 'repeat',
  notes: 'notes',
} as const;

export type ShiftTemplateFormData = Pick<
  ShiftFormData,
  'shiftName' | 'color' | 'timeSlots' | 'notes'
>;

export const SHIFT_TEMPLATE_INITIAL_VALUES = {
  shiftName: '',
  color: COLOR_OPTIONS[0].value,
  timeSlots: [
    {
      id: Date.now(),
      startTime: null,
      endTime: null,
    },
  ],
  notes: '',
};

export const checkIfTemplateValuesWereModified = (
  defaultTemplateFields: ShiftFormData,
  currentFormFields: ShiftFormData,
) => {
  const completedTimeSlots = currentFormFields.timeSlots.filter(
    timeSlot => timeSlot.startTime && timeSlot.endTime,
  );
  return (
    defaultTemplateFields.color !== currentFormFields.color ||
    defaultTemplateFields.shiftName !== currentFormFields.shiftName ||
    defaultTemplateFields.notes !== currentFormFields.notes ||
    !isEqual(defaultTemplateFields.timeSlots, completedTimeSlots)
  );
};

export type RotationDayType = 'shift' | 'rest';

export type RotationDayShiftRef = {
  id: number;
  // Backend identity of the shift within a rotation. Present when the shift
  // was loaded from an existing rotation (edit flow) so it can be echoed back
  // on save; absent for shifts added in the form (the server generates one).
  shiftCode?: string;
  name: string;
  color: string | null;
  description?: string;
  timeSlots: TimeSlot[];
};

export type RotationDay = {
  id: string;
  type: RotationDayType;
  shifts?: RotationDayShiftRef[];
};

export type ShiftRotationFormData = {
  name: string;
  description: string;
  days: RotationDay[];
};

export const shiftRotationFormFields = {
  name: 'name',
  description: 'description',
  days: 'days',
} as const;

export const SHIFT_ROTATION_INITIAL_VALUES: ShiftRotationFormData = {
  name: '',
  description: '',
  days: [],
};

export type DuplicateShiftsFormData = {
  copyRange: DateRange;
  pasteRange: DateRange;
};

export const duplicateShiftsFormFields = {
  copyRange: 'copyRange',
  pasteRange: 'pasteRange',
};

export const DUPLICATE_SHIFTS_INITIAL_VALUES: DuplicateShiftsFormData = {
  copyRange: { fromDate: null, toDate: null },
  pasteRange: { fromDate: null, toDate: null },
};
