import { createSlice, PayloadAction } from '@reduxjs/toolkit';

import { MobileFilterType, Room, TravelerType, TypeaheadOption } from '../types';
import { ReactNode } from 'react';
import { PickerItem } from '../../shared/types';
import { PortalQsmType } from '@qite/tide-client';

export interface QSMState {
  qsmType?: PortalQsmType;
  selectedOrigin?: string;
  selectedDestination?: string;
  selectedAirport?: string;
  fromDate?: string;
  toDate?: string;
  travelers: any[];
  mobileFilterType: MobileFilterType;
  searchResults: TypeaheadOption[];
  activeSearchField: string | null;
  activeSearchFieldProps: {
    fieldKey: string;
    label: string;
    placeholder: string;
    value: string;
    options: TypeaheadOption[];
  } | null;
  mobileDatePickerMode: 'range' | 'single';
  minDate?: string;
  maxDate?: string;
  dateFlexibility?: {
    name: string;
    before: number;
    after: number;
  }[];
  datesIcon?: ReactNode;
  selectedFlexRange?: { before: number; after: number };
  travelTypes: PickerItem[];
  tripType: 'oneway' | 'roundtrip' | 'openjaw';
  selectedTravelType?: string;
  travelClasses: PickerItem[];
  selectedTravelClass?: string;
  selectedNationality?: string;
  defaultTravelers: number;
  maxTravelers: number;
  maxChildAge: number;
  maxInfantAge: number;
  adults: number;
  kids: number;
  babies: number;
  rooms: Room[];
  [key: string]: any;
}

const initialState: QSMState = {
  qsmType: PortalQsmType.AccommodationAndFlight,
  selectedOrigin: undefined,
  selectedDestination: undefined,
  selectedAirport: undefined,
  fromDate: undefined,
  toDate: undefined,
  travelers: [
    {
      adults: 2,
      children: 0,
      childrensAges: []
    }
  ],
  mobileFilterType: null,
  activeSearchField: null,
  activeSearchFieldProps: null,
  searchResults: [],
  mobileDatePickerMode: 'range',
  minDate: undefined,
  maxDate: undefined,
  dateFlexibility: [],
  datesIcon: undefined,
  selectedFlexRange: undefined,
  travelTypes: [],
  selectedTravelType: undefined,
  travelClasses: [],
  tripType: 'roundtrip',
  selectedTravelClass: undefined,
  selectedNationality: undefined,
  defaultTravelers: 2,
  maxTravelers: 9,
  maxChildAge: 12,
  maxInfantAge: 2,
  adults: 2,
  kids: 0,
  babies: 0,
  rooms: [{ adults: 2, kids: 0, babies: 0 }]
};

const qsmSlice = createSlice({
  name: 'qsm',
  initialState,
  reducers: {
    setSelectedQsmType: (state, action: PayloadAction<PortalQsmType>) => {
      state.qsmType = action.payload;
    },
    setOrigin: (state, action: PayloadAction<string>) => {
      state.selectedOrigin = action.payload;
    },
    setDestination: (state, action: PayloadAction<string>) => {
      state.selectedDestination = action.payload;
    },
    setAirport: (state, action: PayloadAction<string>) => {
      state.selectedAirport = action.payload;
    },
    setFromDate: (state, action: PayloadAction<string | undefined>) => {
      state.fromDate = action.payload;
    },
    setFieldValue: (
      state,
      action: PayloadAction<{
        fieldKey: string;
        value: any;
      }>
    ) => {
      const { fieldKey, value } = action.payload;
      (state as any)[fieldKey] = value;
    },
    setToDate: (state, action: PayloadAction<string | undefined>) => {
      state.toDate = action.payload;
    },
    setTravelers: (state, action: PayloadAction<any[]>) => {
      state.travelers = action.payload;
    },
    setMobileFilterType: (state, action: PayloadAction<MobileFilterType>) => {
      state.mobileFilterType = action.payload;
    },
    closeMobileFilter: (state) => {
      state.mobileFilterType = null;
    },
    setActiveSearchField: (state, action: PayloadAction<string | null>) => {
      state.activeSearchField = action.payload;
    },
    setActiveSearchFieldProps: (
      state,
      action: PayloadAction<{
        fieldKey: string;
        label: string;
        placeholder: string;
        value: string;
        options: TypeaheadOption[];
      }>
    ) => {
      state.activeSearchFieldProps = action.payload;
    },
    setSearchResults: (state, action: PayloadAction<TypeaheadOption[]>) => {
      state.searchResults = action.payload;
    },
    setMobileDatePickerMode: (state, action: PayloadAction<'range' | 'single'>) => {
      state.mobileDatePickerMode = action.payload;
    },
    setMinDate: (state, action: PayloadAction<string | undefined>) => {
      state.minDate = action.payload;
    },
    setMaxDate: (state, action: PayloadAction<string | undefined>) => {
      state.maxDate = action.payload;
    },
    setDatesIcon: (state, action: PayloadAction<ReactNode | undefined>) => {
      state.datesIcon = action.payload;
    },
    setDateFlexibility: (state, action: PayloadAction<QSMState['dateFlexibility']>) => {
      state.dateFlexibility = action.payload;
    },
    setSelectedFlexRange: (state, action: PayloadAction<{ before: number; after: number } | undefined>) => {
      state.selectedFlexRange = action.payload;
    },
    setTravelTypes: (state, action: PayloadAction<PickerItem[]>) => {
      state.travelTypes = action.payload;
    },
    setTripType: (state, action: PayloadAction<'oneway' | 'roundtrip' | 'openjaw'>) => {
      state.tripType = action.payload;
    },
    setSelectedTravelType: (state, action) => {
      state.selectedTravelType = action.payload;
    },
    setTravelClasses: (state, action: PayloadAction<PickerItem[]>) => {
      state.travelClasses = action.payload;
    },
    setSelectedTravelClass: (state, action) => {
      state.selectedTravelClass = action.payload;
    },
    setSelectedNationality: (state, action) => {
      state.selectedNationality = action.payload;
    },
    setDefaultTravelers: (state, action: PayloadAction<number>) => {
      state.defaultTravelers = action.payload;
    },
    setMaxTravelers: (state, action: PayloadAction<number>) => {
      state.maxTravelers = action.payload;
    },
    setMaxChildAge: (state, action: PayloadAction<number>) => {
      state.maxChildAge = action.payload;
    },
    setMaxInfantAge: (state, action: PayloadAction<number>) => {
      state.maxInfantAge = action.payload;
    },
    setAdults: (state, action) => {
      state.adults = action.payload;
    },
    setKids: (state, action) => {
      state.kids = action.payload;
    },
    setBabies: (state, action) => {
      state.babies = action.payload;
    },
    setRooms: (state, action) => {
      state.rooms = action.payload;
    },
    addRoom: (state) => {
      if (state.rooms.length < 4) {
        state.rooms.push({ adults: 2, kids: 0, babies: 0 });
      }
    },
    removeRoom: (state, action) => {
      const index = action.payload;
      state.rooms.splice(index, 1);
    },
    updateRoomTraveler: (
      state,
      action: PayloadAction<{
        roomIndex: number;
        type: TravelerType;
        value: number;
      }>
    ) => {
      const { roomIndex, type, value } = action.payload;
      state.rooms[roomIndex][type] = value;
    },
    hydrateQsmState: (state, action: PayloadAction<Partial<QSMState>>) => {
      Object.assign(state, action.payload);

      state.searchResults = [];
      state.activeSearchField = null;
      state.activeSearchFieldProps = null;
      state.mobileFilterType = null;
    }
  }
});

export const {
  setSelectedQsmType,
  setOrigin,
  setDestination,
  setAirport,
  setFromDate,
  setToDate,
  setTravelers,
  setMobileFilterType,
  closeMobileFilter,
  setActiveSearchField,
  setActiveSearchFieldProps,
  setSearchResults,
  setMobileDatePickerMode,
  setMinDate,
  setMaxDate,
  setDateFlexibility,
  setSelectedFlexRange,
  setTripType,
  setTravelTypes,
  setSelectedTravelType,
  setTravelClasses,
  setSelectedTravelClass,
  setSelectedNationality,
  setDefaultTravelers,
  setMaxTravelers,
  setMaxChildAge,
  setAdults,
  setKids,
  setBabies,
  setRooms,
  addRoom,
  removeRoom,
  updateRoomTraveler,
  setMaxInfantAge,
  setDatesIcon,
  setFieldValue,
  hydrateQsmState
} = qsmSlice.actions;
export default qsmSlice.reducer;
