import { ObjectId } from 'bson';
import { FC, useEffect, useState } from 'react';
import { useForm } from 'react-hook-form';
import { toast } from 'sonner';
import { Button, Stack } from '../../components';
import { LeaveType, soriAPIClient, WorkDay, WorkDayType } from '../../lib/sori';
import { DateRangePicker } from '@/components/DateRangePicker';
import { CSelect } from '@/components/ui/c-select';

type CreateLeaveCancellationProps = {
  onClose: () => void;
  open: boolean;
};

type FormValues = {
  type: LeaveType;
  dateRange: { start: Date; end: Date };
  workDayType: WorkDayType;
  remark: string;
};

export const CreateLeaveCancellationForm: FC<CreateLeaveCancellationProps> = ({
  onClose,
  open,
}) => {
  const { register, handleSubmit, reset, setValue, watch } =
    useForm<FormValues>({
      defaultValues: {
        type: 'annual',
        dateRange: { start: new Date(), end: new Date() },
        workDayType: 'full',
        remark: '',
      },
    });
  useEffect(() => {
    if (!open) {
      reset({
        type: 'annual',
        workDayType: 'full',
        dateRange: { start: new Date(), end: new Date() },
        remark: '',
      });
    }
  }, [open]);

  const leaveTypes: LeaveType[] = Object.values(LeaveType.Enum);
  const workDayTypes = Object.values(WorkDayType.Enum);

  const currentWorkDayType = watch('workDayType');
  const currentDateRange = watch('dateRange');
  const [halfDayWarning, setHalfDayWarning] = useState<string | null>(null);

  useEffect(() => {
    if (!currentDateRange.start || !currentDateRange.end) {
      setHalfDayWarning(null);
    } else if (
      currentWorkDayType !== 'full' &&
      currentDateRange.start.getTime() !== currentDateRange.end.getTime()
    ) {
      console.log('currentWorkDayType', currentWorkDayType);
      console.log('currentDateRange', currentDateRange);
      setHalfDayWarning('*Half day can only be applied for a single day.');
    } else {
      setHalfDayWarning(null);
    }
  }, [currentWorkDayType, currentDateRange]);

  const onFormSubmit = async (data: FormValues) => {
    const fromDate = data.dateRange.start;
    const toDate = data.dateRange.end;
    const dayInMs = 1000 * 60 * 60 * 24;
    let fromDateMs = fromDate.getTime();
    const toDateMs = toDate.getTime();
    const dateDiff = toDateMs - fromDateMs;

    let workDays: WorkDay[] = [];
    if (dateDiff === 0) {
      workDays = [
        {
          date: `${fromDate.toDateString()}`,
          type: data.workDayType,
        },
      ];
    } else if (dateDiff === dayInMs) {
      workDays = [
        {
          date: `${fromDate.toDateString()}`,
          type: data.workDayType,
        },
        {
          date: `${toDate.toDateString()}`,
          type: data.workDayType,
        },
      ];
    } else {
      while (fromDateMs <= toDateMs) {
        if (
          new Date(fromDateMs).getDay() === 0 ||
          new Date(fromDateMs).getDay() === 6
        ) {
          fromDateMs = fromDateMs + dayInMs;
        } else {
          workDays.push({
            date: `${new Date(fromDateMs).toDateString()}`,
            type: data.workDayType,
          });
          fromDateMs = fromDateMs + dayInMs;
        }
      }
    }
    const payload = {
      workDays: workDays,
      applyRemarks: data.remark,
      appliedBy: new ObjectId('68d50e6f73dd78e6f9d2e098'),
    };

    const [error] =
      await soriAPIClient.leaveCancellations.actions.createLeaveCancellation(
        payload,
      );
    if (error) {
      console.error(error);
      onClose();
      toast.error('Failed to create leave cancellation');
    } else {
      toast.success('Leave cancellation created successfully');
      onClose();
    }
  };

  return (
    <div>
      <form onSubmit={handleSubmit(onFormSubmit)}>
        <Stack className="w-100vw flex flex-col gap-4 border-gray-200 rounded-lg bg-white p-6 text-black sm:max-w-130 dark:bg-zinc-800 dark:text-white/90">
          <h1 className="text-xl">Create Leave Cancellation</h1>
          <div className="flex flex-col gap-4">
            <div className="flex flex-col gap-1">
              <label>Leave Type</label>
              <CSelect
                options={leaveTypes.map((leaveType) => ({
                  label: leaveType,
                  value: leaveType,
                }))}
                onSelect={(selected) => {
                  const value = selected?.map((opt) => opt.value) ?? [];
                  setValue('type', value[0] as LeaveType);
                }}
              />
            </div>
            <div className="flex flex-col gap-1">
              <label>Full Day/ Half Day</label>
              <CSelect
                options={workDayTypes.map((workDayType) => ({
                  label: workDayType,
                  value: workDayType,
                }))}
                onSelect={(selected) => {
                  const value = selected?.map((opt) => opt.value) ?? [];
                  setValue('workDayType', value[0] as WorkDayType);
                }}
              />
            </div>

            <div className="flex flex-col gap-1">
              <label>Dates</label>
              <label className="text-xs text-red-6">{halfDayWarning}</label>
              <DateRangePicker
                onChange={(range) => {
                  setValue('dateRange', {
                    start: range[0],
                    end: range[1],
                  });
                }}
              />
            </div>
            <div className="flex flex-col gap-1">
              <label>Remark</label>
              <textarea
                {...register('remark')}
                rows={3}
                className="border border-zinc-300 rounded px-2 py-1"
              />
            </div>
          </div>

          <Button className="mt-auto bg-blue-5 text-white" type="submit">
            Save
          </Button>
        </Stack>
      </form>
    </div>
  );
};
