import { scheduleAPIService } from '@/api/schedule/schedule.api.service';
import { PickerType, ScheduleData } from '@/types/schedule/schedule-v2.types';
import logger from '@/utils/errorLogger';
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';

interface scheduleState {
  isSettingsDrawerOpen: boolean;
  isScheduleDrawerOpen: boolean;
  workingDays: string[];
  workingHours: number;
  teamData: any[];
  dateList: any;
  loading: boolean;
  error: string | null;
  type: PickerType;
  date: Date;
  dayCount: number;
}

const initialState: scheduleState = {
  isSettingsDrawerOpen: false,
  isScheduleDrawerOpen: false,
  workingDays: [],
  workingHours: 8,
  teamData: [],
  dateList: {},
  loading: false,
  error: null,
  type: 'month',
  date: new Date(),
  dayCount: 0,
};

export const fetchTeamData = createAsyncThunk('schedule/fetchTeamData', async () => {
  const response = await scheduleAPIService.fetchScheduleMembers();
  if (!response.done) {
    throw new Error('Failed to fetch team data');
  }
  const data = response.body;
  return data;
});

export const fetchDateList = createAsyncThunk(
  'schedule/fetchDateList',
  async ({ date, type }: { date: Date; type: string }) => {
    const response = await scheduleAPIService.fetchScheduleDates({ date: date.toISOString(), type });
    if (!response.done) {
      throw new Error('Failed to fetch date list');
    }
    const data = response.body;
    return data;
  }
);

export const updateWorking = createAsyncThunk(
  'schedule/updateWorking',
  async ({ workingDays, workingHours }: { workingDays: string[]; workingHours: number }) => {
    const response = await scheduleAPIService.updateScheduleSettings({ workingDays, workingHours });
    if (!response.done) {
      throw new Error('Failed to fetch date list');
    }
    const data = response.body;
    return data;
  }
);

export const getWorking = createAsyncThunk(
  'schedule/getWorking',
  async (_, { rejectWithValue }) => {
    try {
      const response = await scheduleAPIService.fetchScheduleSettings();
      if (!response.done) {
        throw new Error('Failed to fetch date list');
      }
      return response;
    } catch (error) {
      logger.error('getWorking', error);
      if (error instanceof Error) {
        return rejectWithValue(error.message);
      }
      return rejectWithValue('Failed to getWorking');
    }
  }
);

export const fetchMemberProjects = createAsyncThunk(
  'schedule/fetchMemberProjects',
  async ({ id }: { id: string }) => {
    const response = await scheduleAPIService.fetchMemberProjects({ id });
    if (!response.done) {
      throw new Error('Failed to fetch date list');
    }
    const data = response.body;
    return data;
  }
);

export const createSchedule = createAsyncThunk(
  'schedule/createSchedule',
  async ({ schedule }: { schedule: ScheduleData}) => {
    const response = await scheduleAPIService.submitScheduleData({ schedule });
    if (!response.done) {
      throw new Error('Failed to fetch date list');
    }
    const data = response.body;
    return data;
  }
);

const scheduleSlice = createSlice({
  name: 'scheduleReducer',
  initialState,
  reducers: {
    toggleSettingsDrawer: state => {
      state.isSettingsDrawerOpen = !state.isSettingsDrawerOpen;
    },
    updateSettings(state, action) {
      state.workingDays = action.payload.workingDays;
      state.workingHours = action.payload.workingHours;
    },
    toggleScheduleDrawer: state => {
      state.isScheduleDrawerOpen = !state.isScheduleDrawerOpen;
    },
    getWorkingSettings(state, action) {
      state.workingDays = action.payload.workingDays;
      state.workingHours = action.payload.workingHours;
    },
    setDate(state, action) {
      state.date = action.payload;
    },
    setType(state, action) {
      state.type = action.payload;
    },
    setDayCount(state, action) {
      state.dayCount = action.payload;
    },
  },
  extraReducers: builder => {
    builder
      .addCase(fetchTeamData.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchTeamData.fulfilled, (state, action) => {
        state.teamData = action.payload;
        state.loading = false;
      })
      .addCase(fetchTeamData.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to fetch team data';
      })
      .addCase(fetchDateList.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchDateList.fulfilled, (state, action) => {
        state.dateList = action.payload;
        state.dayCount = (action.payload as any)?.date_data[0]?.days?.length;
        state.loading = false;
      })
      .addCase(fetchDateList.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to fetch date list';
      })
      .addCase(updateWorking.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(updateWorking.fulfilled, (state, action) => {
        state.workingDays = action.payload.workingDays;
        state.workingHours = action.payload.workingHours;
        state.loading = false;
      })
      .addCase(updateWorking.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to fetch date list';
      })
      .addCase(getWorking.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(getWorking.fulfilled, (state, action) => {
        state.workingDays = action.payload.body.workingDays;
        state.workingHours = action.payload.body.workingHours;
        state.loading = false;
      })
      .addCase(getWorking.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to fetch list';
      }).addCase(fetchMemberProjects.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(fetchMemberProjects.fulfilled, (state, action) => {
        const data = action.payload;

        state.teamData.find((team: any) => {
          if (team.id === data.id) {
            team.projects = data.projects||[];
          }
        })
        state.loading = false;
      })
      .addCase(fetchMemberProjects.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to fetch date list';
      }).addCase(createSchedule.pending, state => {
        state.loading = true;
        state.error = null;
      })
      .addCase(createSchedule.fulfilled, (state, action) => {
        state.loading = false;
      })
      .addCase(createSchedule.rejected, (state, action) => {
        state.loading = false;
        state.error = action.error.message || 'Failed to send schedule';
      });
  },
});

export const { toggleSettingsDrawer, updateSettings, toggleScheduleDrawer, getWorkingSettings, setDate, setType, setDayCount } =
  scheduleSlice.actions;
export default scheduleSlice.reducer;
