import React, { useContext, useEffect, useMemo, useRef } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { QSMRootState } from '../../store/qsm-store';
import QSMConfigurationContext from '../../qsm-configuration-context';
import useMediaQuery from '../../../shared/utils/use-media-query-util';
import MobileFilterModal from '../mobile-filter-modal';
import SearchInputGroup from '../search-input-group';
import DoubleSearchInputGroup from '../double-search-input-group';
import Dates from '../../../booking-product/components/dates';
import TravelInputGroup from '../travel-input-group';
import TravelClassPicker from '../travel-class-picker';
import TravelTypePicker from '../travel-type-picker';
import Icon from '../../../shared/components/icon';
import TravelNationalityPicker from '../travel-nationality-picker';
import { addDays, addMonths, addYears, format } from 'date-fns';
import { DateRange } from '../../../booking-product/types';
import { hydrateQsmState, QSMState, setFromDate, setSelectedQsmType, setToDate, setTripType } from '../../store/qsm-slice';
import { BaseFieldConfig, DoubleFieldConfig } from '../../types';
import { getTranslations } from '../../../shared/utils/localization-util';
import { DateAmountType, PortalQsmType } from '@qite/tide-client';
import { first } from 'lodash';

const QSMContainer: React.FC = () => {
  const dispatch = useDispatch();
  const isMobile = useMediaQuery('(max-width: 768px)');
  const qsmState = useSelector((state: QSMRootState) => state.qsm);
  const { qsmType, mobileFilterType, fromDate, toDate, tripType } = qsmState;
  const {
    askTravelers,
    askRooms,
    askNationality,
    askTravelClass,
    askTravelType,
    submitIcon,
    onSubmit,
    travelTypes,
    languageCode,
    departureAirport,
    destinationAirport,
    returnAirport,
    destination,
    allowOneWay,
    allowRoundtrip,
    allowOpenJaw,
    searchConfigurations
  } = useContext(QSMConfigurationContext);
  const translations = getTranslations(languageCode ?? 'en-GB');

  useEffect(() => {
    if (!hasHydratedFromSession.current) return;

    const stored = sessionStorage.getItem(QSM_SESSION_STORAGE_KEY);
    const storedQsmType = stored ? JSON.parse(stored).qsmType : undefined;

    if (storedQsmType) return;

    const defaultQsmType = first(searchConfigurations)?.qsmType;
    if (!defaultQsmType) return;

    handleQsmTypeChange(defaultQsmType);
  }, [searchConfigurations]);

  useEffect(() => {
    if (fromDate || toDate) return;

    let startDate = addMonths(new Date(), 1);
    let endDate = addDays(startDate, 7);

    if (qsmType === PortalQsmType.GroupTour) {
      startDate = new Date();
      endDate = addYears(startDate, 1);
    }

    dispatch(setFromDate(startDate.toISOString()));
    dispatch(setToDate(endDate.toISOString()));
  }, [fromDate, toDate, dispatch]);

  const dateRange = useMemo<DateRange | undefined>(() => {
    if (!fromDate || !toDate) return undefined;

    return {
      fromDate: new Date(fromDate),
      toDate: new Date(toDate)
    };
  }, [fromDate, toDate]);

  const QSM_SESSION_STORAGE_KEY = 'qsm-state';

  const hasHydratedFromSession = useRef(false);

  useEffect(() => {
    try {
      const stored = sessionStorage.getItem(QSM_SESSION_STORAGE_KEY);

      if (stored) {
        dispatch(hydrateQsmState(JSON.parse(stored)));
      }
    } catch {
      sessionStorage.removeItem(QSM_SESSION_STORAGE_KEY);
    } finally {
      hasHydratedFromSession.current = true;
    }
  }, [dispatch]);

  const handleDateChange = (value: DateRange) => {
    dispatch(setFromDate(value.fromDate ? format(value.fromDate, 'yyyy-MM-dd') : undefined));
    dispatch(setToDate(value.toDate ? format(value.toDate, 'yyyy-MM-dd') : undefined));
  };

  const handleTripTypeChange = (value: 'oneway' | 'roundtrip' | 'openjaw') => {
    dispatch(setTripType(value));
  };

  const handleQsmTypeChange = (value: PortalQsmType) => {
    dispatch(setSelectedQsmType(value));

    const now = new Date();

    // Default fallback
    let startDate = addMonths(now, 1);
    let endDate = addDays(startDate, 7);
    if (value === PortalQsmType.GroupTour) {
      startDate = now;
      endDate = addYears(startDate, 1);
    }

    const searchConfig = searchConfigurations.find((config) => config.qsmType === value);

    if (searchConfig) {
      const applyAmount = (baseDate: Date, type: DateAmountType, amount?: number) => {
        if (!amount || type == null) return baseDate;

        switch (type) {
          case DateAmountType.days:
            return addDays(baseDate, amount);
          case DateAmountType.months:
            return addMonths(baseDate, amount);
          default:
            return baseDate;
        }
      };

      if (searchConfig.fromDateAmount) {
        startDate = applyAmount(now, searchConfig.fromDateAmountType, searchConfig.fromDateAmount);
      }

      if (searchConfig.toDateAmount) {
        endDate = applyAmount(startDate, searchConfig.toDateAmountType, searchConfig.toDateAmount);
      }
    }

    handleDateChange({
      fromDate: startDate,
      toDate: endDate
    });
  };

  const handleSubmit = () => {
    if (!onSubmit) return;

    const { qsmType, fromDate, toDate, selectedTravelClass, selectedTravelType, selectedNationality, rooms, tripType, adults, kids, babies } = qsmState;

    const selectedTravelTypeValue = travelTypes?.find((t) => t.label === selectedTravelType);
    const payload = {
      qsmType,
      fromDate,
      toDate,
      travelClass: selectedTravelClass,
      travelType: selectedTravelTypeValue,
      nationality: selectedNationality,
      tripType
    } as any;

    if (askRooms && qsmType !== PortalQsmType.Flight) {
      payload.rooms = rooms;
    } else {
      payload.travelers = { adults, kids, babies };
    }

    // Filter out undefined fields before passing to addSearchFieldsToPayload
    const searchFields = [departureAirport, destinationAirport, returnAirport, destination].filter((field): field is BaseFieldConfig => field !== undefined);
    addSearchFieldsToPayload(payload, searchFields, qsmState);

    if (destination) {
      const option = destination.options.find((opt) => opt.value === qsmState[destination.fieldKey]);
      if (option) {
        payload.destinationType = option?.type;
      }
    }

    onSubmit(payload);
    console.log('Submitted QSM data:', payload);
  };

  const addSearchFieldsToPayload = (payload: any, fields: BaseFieldConfig[], state: QSMState) => {
    fields.forEach((field) => {
      const fieldKey = field.fieldKey;
      const option = field.options.find((opt) => opt.value === state[fieldKey]);
      payload[fieldKey] = option?.key ?? state[fieldKey];
    });
  };

  const originDestinationField = useMemo<DoubleFieldConfig | undefined>(() => {
    if (!fromDate || !toDate || !departureAirport || !destinationAirport) return undefined;

    const departureField: BaseFieldConfig = {
      ...departureAirport,
      label: translations.QSM.DEPARTURE,
      placeholder: translations.QSM.CHOOSE_DEPARTURE
    };

    const destinationField: BaseFieldConfig = {
      ...destinationAirport,
      label: translations.QSM.DESTINATION,
      placeholder: translations.QSM.CHOOSE_DESTINATION
    };

    return {
      type: 'double',
      fieldKey: 'locationGroup',
      showReverse: true,
      fields: [departureField, destinationField]
    };
  }, [fromDate, toDate, departureAirport, destinationAirport, translations]);

  const openJawReturnDestinationField = useMemo<DoubleFieldConfig | undefined>(() => {
    if (!fromDate || !toDate || !allowOpenJaw || !departureAirport || !returnAirport) return undefined;

    const mirroredDepartureField: BaseFieldConfig = {
      ...departureAirport,
      label: translations.QSM.DESTINATION,
      placeholder: translations.QSM.CHOOSE_DESTINATION
    };

    return {
      type: 'double',
      fieldKey: 'openjawLocationGroup',
      showReverse: false,
      disableReturnField: true,
      fields: [returnAirport, mirroredDepartureField]
    };
  }, [fromDate, toDate, departureAirport, returnAirport, allowOpenJaw]);

  const qsmTypeMeta: Record<PortalQsmType, { icon: string | string[]; label: string }> = {
    [PortalQsmType.Multidestination]: {
      icon: 'ui-location',
      label: translations.QSM.MULTIDESTINATION
    },
    [PortalQsmType.Package]: {
      icon: 'ui-suitcase',
      label: translations.QSM.PACKAGES
    },
    [PortalQsmType.AccommodationAndFlight]: {
      icon: ['ui-backforward', 'ui-bed'],
      label: translations.QSM.TRANSPORT_HOTEL
    },
    [PortalQsmType.Accommodation]: {
      icon: 'ui-bed',
      label: translations.QSM.ACCOMMODATION
    },
    [PortalQsmType.Flight]: {
      icon: 'ui-flight',
      label: translations.QSM.TRANSPORTS
    },
    [PortalQsmType.GroupTour]: {
      icon: 'ui-group',
      label: translations.QSM.GROUP_TOUR
    },
    [PortalQsmType.RoundTrip]: {
      icon: 'ui-group',
      label: translations.QSM.ROUNDTRIP
    },
    [PortalQsmType.Ticket]: {
      icon: 'ui-ticket',
      label: translations.QSM.TICKET_ONLY
    },
    [PortalQsmType.Car]: {
      icon: 'ui-car',
      label: translations.QSM.RENT_A_CAR
    },
    [PortalQsmType.Transfer]: {
      icon: 'ui-backforward',
      label: translations.QSM.TRANSFERS
    },
    [PortalQsmType.Cruise]: {
      icon: 'ui-ship',
      label: translations.QSM.CRUISES
    }
  };

  useEffect(() => {
    if (!hasHydratedFromSession.current) return;

    const searchFields = [departureAirport, destinationAirport, returnAirport, destination].filter((field): field is BaseFieldConfig => field !== undefined);

    const dynamicFields = searchFields.reduce<Record<string, any>>((result, field) => {
      result[field.fieldKey] = qsmState[field.fieldKey];
      return result;
    }, {});

    const stateToPersist: Partial<QSMState> = {
      qsmType,
      fromDate,
      toDate,
      tripType,
      selectedTravelClass: qsmState.selectedTravelClass,
      selectedTravelType: qsmState.selectedTravelType,
      selectedNationality: qsmState.selectedNationality,
      adults: qsmState.adults,
      kids: qsmState.kids,
      babies: qsmState.babies,
      rooms: qsmState.rooms,
      travelers: qsmState.travelers,
      ...dynamicFields
    };

    sessionStorage.setItem(QSM_SESSION_STORAGE_KEY, JSON.stringify(stateToPersist));
  }, [qsmState, qsmType, fromDate, toDate, tripType, departureAirport, destinationAirport, returnAirport, destination]);

  return (
    <div className="qsm">
      <div className="qsm__content">
        <div className="qsm__tabs">
          {searchConfigurations.map((searchConfig, index) => {
            const meta = qsmTypeMeta[searchConfig.qsmType];

            if (!meta) return null; // safety guard

            return (
              <button
                key={`qsm-type-${index}`}
                type="button"
                className={`qsm__tab ${qsmType === searchConfig.qsmType ? 'qsm__tab--active' : ''}`}
                onClick={() => handleQsmTypeChange(searchConfig.qsmType)}>
                <span className="qsm__tab__icons">
                  {Array.isArray(meta.icon) ? meta.icon.map((icon, i) => <Icon key={i} name={icon} height={14} />) : <Icon name={meta.icon} height={16} />}
                </span>

                {meta.label}
              </button>
            );
          })}
          {/* 
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Multidestination ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Multidestination)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-location" height={16} />
            </span>
            {translations.QSM.MULTIDESTINATION}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Package ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Package)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-suitcase" height={16} />
            </span>
            {translations.QSM.PACKAGES}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.AccommodationAndFlight ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.AccommodationAndFlight)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-backforward" height={14} />
              +
              <Icon name="ui-bed" height={14} />
            </span>
            {translations.QSM.TRANSPORT_HOTEL}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Accommodation ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Accommodation)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-bed" height={16} />
            </span>
            {translations.QSM.ACCOMMODATION}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Flight ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Flight)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-flight" height={16} />
            </span>
            {translations.QSM.TRANSPORTS}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.GroupTour ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.GroupTour)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-group" height={16} />
            </span>
            {translations.QSM.GROUP_TOUR}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Ticket ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Ticket)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-ticket" height={16} />
            </span>
            {translations.QSM.TICKET_ONLY}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Car ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Car)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-car" height={16} />
            </span>
            {translations.QSM.RENT_A_CAR}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Transfer ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Transfer)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-backforward" height={16} />
            </span>
            {translations.QSM.TRANSFERS}
          </button>
          <button
            type="button"
            className={`qsm__tab ${qsmType == PortalQsmType.Cruise ? 'qsm__tab--active' : ''}`}
            onClick={() => handleQsmTypeChange(PortalQsmType.Cruise)}>
            <span className="qsm__tab__icons">
              <Icon name="ui-ship" height={16} />
            </span>
            {translations.QSM.CRUISES}
          </button> */}
        </div>
        {!isMobile && (
          <div className="qsm__filter">
            {(qsmType === PortalQsmType.Accommodation || qsmType === PortalQsmType.AccommodationAndFlight || qsmType === PortalQsmType.GroupTour) && (
              <div className="radiobutton-group qsm__filter__inputgroup">
                <div className="radiobutton">
                  <label className="radiobutton__label">
                    <input
                      type="radio"
                      name="numberOfAccommodations"
                      // onChange={handleMainBookerChange}
                      // onBlur={formik.handleBlur}
                      value=""
                      checked={true}
                      readOnly
                      className="radiobutton__input"
                    />
                    <span>{translations.QSM.ONE_ACCOMMODATION}</span>
                  </label>
                </div>
                <div className="radiobutton">
                  <label className="radiobutton__label">
                    <input
                      type="radio"
                      name="numberOfAccommodations"
                      // onChange={handleMainBookerChange}
                      // onBlur={formik.handleBlur}
                      value=""
                      className="radiobutton__input"
                      disabled={true}
                    />
                    <span>{translations.QSM.MULTIPLE_ACCOMMODATIONS}</span>
                  </label>
                </div>
              </div>
            )}
            {qsmType === PortalQsmType.Flight && (
              <div className="radiobutton-group qsm__filter__inputgroup">
                {allowOneWay && (
                  <div className="radiobutton">
                    <label className="radiobutton__label">
                      <input
                        type="radio"
                        name="tripType"
                        value="oneway"
                        checked={tripType === 'oneway'}
                        onChange={() => handleTripTypeChange('oneway')}
                        className="radiobutton__input"
                      />
                      <span>{translations.QSM.ONEWAY}</span>
                    </label>
                  </div>
                )}

                {allowRoundtrip && (
                  <div className="radiobutton">
                    <label className="radiobutton__label">
                      <input
                        type="radio"
                        name="tripType"
                        value="roundtrip"
                        checked={tripType === 'roundtrip'}
                        onChange={() => handleTripTypeChange('roundtrip')}
                        className="radiobutton__input"
                      />
                      <span>{translations.QSM.ROUNDTRIP}</span>
                    </label>
                  </div>
                )}

                {allowOpenJaw && (
                  <div className="radiobutton">
                    <label className="radiobutton__label">
                      <input
                        type="radio"
                        name="tripType"
                        value="openjaw"
                        checked={tripType === 'openjaw'}
                        onChange={() => handleTripTypeChange('openjaw')}
                        className="radiobutton__input"
                      />
                      <span>{translations.QSM.OPENJAW}</span>
                    </label>
                  </div>
                )}
              </div>
            )}
            <div className="qsm__filter__classgroup">
              {qsmType !== PortalQsmType.Accommodation &&
                qsmType !== PortalQsmType.Car &&
                qsmType !== PortalQsmType.Ticket &&
                qsmType !== PortalQsmType.Cruise &&
                qsmType !== PortalQsmType.Transfer &&
                qsmType !== PortalQsmType.GroupTour &&
                askTravelClass && <TravelClassPicker />}
              {qsmType !== PortalQsmType.Multidestination &&
                qsmType !== PortalQsmType.Car &&
                qsmType !== PortalQsmType.Flight &&
                qsmType !== PortalQsmType.Transfer &&
                askTravelType && <TravelTypePicker />}
              {askNationality && <TravelNationalityPicker />}
            </div>
          </div>
        )}
        <div className="qsm__input-group">
          {/* TODO, determine which fields to show for what type of QSM */}
          {(qsmType == PortalQsmType.Flight || qsmType == PortalQsmType.AccommodationAndFlight) && originDestinationField && (
            <DoubleSearchInputGroup fieldConfig={originDestinationField} showReverse={originDestinationField.showReverse} />
          )}
          {qsmType == PortalQsmType.Flight && tripType == 'openjaw' && openJawReturnDestinationField && (
            <DoubleSearchInputGroup fieldConfig={openJawReturnDestinationField} showReverse={openJawReturnDestinationField.showReverse} />
          )}
          {(qsmType == PortalQsmType.Accommodation || qsmType == PortalQsmType.AccommodationAndFlight || qsmType == PortalQsmType.GroupTour) && destination && (
            <SearchInputGroup fieldConfig={destination} />
          )}

          <Dates value={dateRange} onChange={handleDateChange} />

          {askTravelers && <TravelInputGroup />}

          {isMobile && (
            <div className="qsm__filter">
              {(qsmType === PortalQsmType.Accommodation || qsmType === PortalQsmType.AccommodationAndFlight || qsmType === PortalQsmType.GroupTour) && (
                <div className="radiobutton-group qsm__filter__inputgroup">
                  <div className="radiobutton">
                    <label className="radiobutton__label">
                      <input
                        type="radio"
                        name="numberOfAccommodations"
                        // onChange={handleMainBookerChange}
                        // onBlur={formik.handleBlur}
                        value=""
                        checked={true}
                        readOnly
                        className="radiobutton__input"
                      />
                      <span>{translations.QSM.ONE_ACCOMMODATION}</span>
                    </label>
                  </div>
                  <div className="radiobutton">
                    <label className="radiobutton__label">
                      <input
                        type="radio"
                        name="numberOfAccommodations"
                        // onChange={handleMainBookerChange}
                        // onBlur={formik.handleBlur}
                        value=""
                        className="radiobutton__input"
                        disabled={true}
                      />
                      <span>{translations.QSM.MULTIPLE_ACCOMMODATIONS}</span>
                    </label>
                  </div>
                </div>
              )}
              {qsmType === PortalQsmType.Flight && (
                <div className="radiobutton-group qsm__filter__inputgroup">
                  {allowOneWay && (
                    <div className="radiobutton">
                      <label className="radiobutton__label">
                        <input
                          type="radio"
                          name="tripType"
                          value="oneway"
                          checked={tripType === 'oneway'}
                          onChange={() => handleTripTypeChange('oneway')}
                          className="radiobutton__input"
                        />
                        <span>{translations.QSM.ONEWAY}</span>
                      </label>
                    </div>
                  )}

                  {allowRoundtrip && (
                    <div className="radiobutton">
                      <label className="radiobutton__label">
                        <input
                          type="radio"
                          name="tripType"
                          value="roundtrip"
                          checked={tripType === 'roundtrip'}
                          onChange={() => handleTripTypeChange('roundtrip')}
                          className="radiobutton__input"
                        />
                        <span>{translations.QSM.ROUNDTRIP}</span>
                      </label>
                    </div>
                  )}

                  {allowOpenJaw && (
                    <div className="radiobutton">
                      <label className="radiobutton__label">
                        <input
                          type="radio"
                          name="tripType"
                          value="openjaw"
                          checked={tripType === 'openjaw'}
                          onChange={() => handleTripTypeChange('openjaw')}
                          className="radiobutton__input"
                        />
                        <span>{translations.QSM.OPENJAW}</span>
                      </label>
                    </div>
                  )}
                </div>
              )}
              <div className="qsm__filter__classgroup">
                {qsmType !== PortalQsmType.Accommodation &&
                  qsmType !== PortalQsmType.Car &&
                  qsmType !== PortalQsmType.Ticket &&
                  qsmType !== PortalQsmType.Cruise &&
                  qsmType !== PortalQsmType.Transfer &&
                  qsmType !== PortalQsmType.GroupTour &&
                  askTravelClass && <TravelClassPicker />}
                {qsmType !== PortalQsmType.Multidestination &&
                  qsmType !== PortalQsmType.Car &&
                  qsmType !== PortalQsmType.Flight &&
                  qsmType !== PortalQsmType.Transfer &&
                  askTravelType && <TravelTypePicker />}
                {askNationality && <TravelNationalityPicker />}
              </div>
            </div>
          )}

          <button type="button" className="cta" onClick={handleSubmit}>
            {submitIcon && submitIcon.toString().length > 0 && <span>{submitIcon}</span>}
            <span>{translations.QSM.CONFIRM}</span>
          </button>
        </div>
      </div>
      {isMobile && mobileFilterType && <MobileFilterModal />}
    </div>
  );
};

export default QSMContainer;
