import { useSocket } from "@/socket/socketContext";
import { IProjectTask } from "@/types/project/projectTasksViewModel.types";
import { DatePicker } from "antd";
import dayjs from 'dayjs';
import calendar from 'dayjs/plugin/calendar';
import { SocketEvents } from '@/shared/socket-events';
import type { Dayjs } from 'dayjs';
import { useTranslation } from "react-i18next";
import { useEffect, useState, useMemo } from "react";
import { useAppSelector } from "@/hooks/useAppSelector";
import { useGetMyTasksQuery } from "@/api/home-page/home-page.api.service";
import { getUserSession } from "@/utils/session-helper";

// Extend dayjs with the calendar plugin
dayjs.extend(calendar);

type HomeTasksDatePickerProps = {
    record: IProjectTask;
};

const HomeTasksDatePicker = ({ record }: HomeTasksDatePickerProps) => {
    const { socket, connected } = useSocket();
    const { t } = useTranslation('home');
    const { homeTasksConfig } = useAppSelector(state => state.homePageReducer);
    const { refetch } = useGetMyTasksQuery(homeTasksConfig, {
        skip: false
    });

    // Use useMemo to avoid re-renders when record.end_date is the same
    const initialDate = useMemo(() =>
        record.end_date ? dayjs(record.end_date) : null
        , [record.end_date]);

    const [selectedDate, setSelectedDate] = useState<Dayjs | null>(initialDate);

    // Update selected date when record changes
    useEffect(() => {
        setSelectedDate(initialDate);
    }, [initialDate]);

    const handleChangeReceived = (value: any) => {
        refetch();
    };

    useEffect(() => {
        socket?.on(SocketEvents.TASK_END_DATE_CHANGE.toString(), handleChangeReceived);
        socket?.on(SocketEvents.TASK_STATUS_CHANGE.toString(), handleChangeReceived);
        return () => {
            socket?.removeListener(SocketEvents.TASK_END_DATE_CHANGE.toString(), handleChangeReceived);
            socket?.removeListener(SocketEvents.TASK_STATUS_CHANGE.toString(), handleChangeReceived);
        };
    }, [connected]);

    const handleEndDateChanged = (value: Dayjs | null, task: IProjectTask) => {
        setSelectedDate(value);
        if (!task.id) return;

        const body = {
            task_id: task.id,
            end_date: value?.format('YYYY-MM-DD'),
            parent_task: task.parent_task_id,
            time_zone: getUserSession()?.timezone_name
                ? getUserSession()?.timezone_name
                : Intl.DateTimeFormat().resolvedOptions().timeZone,
        };
        socket?.emit(SocketEvents.TASK_END_DATE_CHANGE.toString(), JSON.stringify(body));
    };

    // Function to dynamically format the date based on the calendar rules
    const getFormattedDate = (date: Dayjs | null) => {
        if (!date) return '';

        return date.calendar(null, {
            sameDay: '[Today]',
            nextDay: '[Tomorrow]',
            nextWeek: 'MMM DD',
            lastDay: '[Yesterday]',
            lastWeek: 'MMM DD',
            sameElse: date.year() === dayjs().year() ? 'MMM DD' : 'MMM DD, YYYY',
        });
    };

    return (
        <DatePicker
            allowClear
            disabledDate={
                record.start_date ? current => current.isBefore(dayjs(record.start_date)) : undefined
            }
            placeholder={t('tasks.dueDatePlaceholder')}
            value={selectedDate}
            onChange={value => handleEndDateChanged(value || null, record || null)}
            format={(value) => getFormattedDate(value)} // Dynamically format the displayed value
            style={{
                color: selectedDate
                    ? selectedDate.isSame(dayjs(), 'day') || selectedDate.isSame(dayjs().add(1, 'day'), 'day')
                        ? '#52c41a'
                        : selectedDate.isAfter(dayjs().add(1, 'day'), 'day')
                            ? undefined
                            : '#ff4d4f'
                    : undefined,
                width: '125px', // Ensure the input takes full width
            }}
            inputReadOnly // Prevent manual input to avoid overflow issues
            variant={'borderless'} // Make the DatePicker borderless
            suffixIcon={null}
        />
    );
};

export default HomeTasksDatePicker;