import { Image } from '@tarojs/components';
import Taro from '@tarojs/taro';

import { forwardRef, useCallback, useEffect, useImperativeHandle, useState } from 'react';

import BlFormItem from '@/components/bl-form-item';
import { BlFormRadio, BlFormRadioGroup } from '@/components/bl-form-radio';
import BlFormSelect from '@/components/bl-form-select';
import { EventName, OpenSource, PageUrl } from '@/constants/app';
import { CITY_CODE_TO_NAME_MAP } from '@/constants/city';
import { EmployType, EMPLOY_TYPE_TITLE_MAP, FULL_PRICE_OPTIONS, PART_PRICE_OPTIONS } from '@/constants/job';
import { SalaryRange } from '@/types/job';
import { MaterialProfile } from '@/types/material';
import { logWithPrefix } from '@/utils/common';
import { isFullTimePriceRequired, isPartTimePriceRequired } from '@/utils/job'
import { getCurrentCity } from '@/utils/location';
import { navigateTo } from '@/utils/route';

import './index.less';

interface IProps {
  profile: Partial<MaterialProfile>;
}

const PREFIX = 'fragment-profile-intention';
const log = logWithPrefix(PREFIX);
const realtimeLogger = Taro.getRealtimeLogManager();
realtimeLogger.tag(PREFIX);
const calcInitCityCodes = (codeString: string = '') => {
  const codes = codeString.split('、');
  return codes.filter(code => !!CITY_CODE_TO_NAME_MAP.get(code));
};

const getCityCodeString = (codes: string[]) => {
  return codes.join('、');
};

const calcSalarySelect = (profile: Partial<MaterialProfile>, full: boolean) => {
  const min = full ? profile.fullTimeMinPrice : profile.partyTimeMinPrice;
  const max = full ? profile.fullTimeMaxPrice : profile.partyTimeMaxPrice;
  if (!min || !max) {
    return;
  }
  const options = full ? FULL_PRICE_OPTIONS : PART_PRICE_OPTIONS;
  return options.find(v => v.value && v.value.minSalary <= min && v.value.maxSalary >= max)?.value;
};

const getSalaryPrice = (fullSalary?: SalaryRange, partSalary?: SalaryRange) => {
  const price: Partial<
    Pick<MaterialProfile, 'fullTimeMinPrice' | 'fullTimeMaxPrice' | 'partyTimeMinPrice' | 'partyTimeMaxPrice'>
  > = {};
  if (fullSalary) {
    price.fullTimeMinPrice = fullSalary.minSalary;
    price.fullTimeMaxPrice = fullSalary.maxSalary;
  }
  if (partSalary) {
    price.partyTimeMinPrice = partSalary.minSalary;
    price.partyTimeMaxPrice = partSalary.maxSalary;
  }
  return price;
};

function ProfileIntentionFragment(props: IProps, ref) {
  const { profile } = props;
  const [cityCodes, setCityCodes] = useState(calcInitCityCodes(profile.cityCodes));
  const [employType, setEmployType] = useState(profile.employType);
  const [fullSalary, setFullSalary] = useState(calcSalarySelect(profile, true));
  const [partSalary, setPartSalary] = useState(calcSalarySelect(profile, false));
  const [acceptWorkForSit, setAcceptWorkForSit] = useState(profile.acceptWorkForSit);

  const handleDeleteCity = useCallback(
    (deleteCode: string) => {
      setCityCodes(cityCodes.filter(code => code !== deleteCode));
    },
    [cityCodes]
  );

  const handleClickAddCity = useCallback(() => {
    const currentCity = getCurrentCity();
    navigateTo(PageUrl.CitySearch, { city: currentCity, source: OpenSource.AddIndentCity });
  }, []);

  const handleSelectCity = useCallback(
    data => {
      log('handleSelectCity', data);
      realtimeLogger.info('handleSelectCity', data);
      const { openSource, cityCode: code } = data;
      if (openSource !== OpenSource.AddIndentCity) {
        return;
      }
      const newCodes = [...new Set([...cityCodes, code])];
      setCityCodes(newCodes);
    },
    [cityCodes]
  );

  const handleEmployTypeChange = useCallback((value: EmployType) => {
    setEmployType(value);
    if (value === EmployType.Full) {
      setPartSalary({ minSalary: 0, maxSalary: 0 })
    }
    if (value === EmployType.Part) {
      setFullSalary({ minSalary: 0, maxSalary: 0 })
    }
  }, []);

  const handleSelectFullSalary = useCallback((value?: SalaryRange) => {
    setFullSalary(value);
  }, []);

  const handleSelectPartSalary = useCallback((value?: SalaryRange) => {
    setPartSalary(value);
  }, []);

  const handleAcceptSittingChange = useCallback((value: boolean) => {
    log('handleAcceptSittingChange', value);
    setAcceptWorkForSit(value);
  }, []);

  useEffect(() => {
    Taro.eventCenter.on(EventName.SELECT_CITY, handleSelectCity);
    return () => {
      Taro.eventCenter.off(EventName.SELECT_CITY, handleSelectCity);
    };
  }, [handleSelectCity]);

  useImperativeHandle(
    ref,
    () => ({
      getData: () => ({
        cityCodes: getCityCodeString(cityCodes),
        employType,
        acceptWorkForSit,
        ...getSalaryPrice(fullSalary, partSalary),
      }),
    }),
    [cityCodes, employType, fullSalary, partSalary, acceptWorkForSit]
  );

  return (
    <div className={PREFIX}>
      <BlFormItem title="意向城市" contentClassName={`${PREFIX}__indent-city-container`} dynamicHeight>
        <div className={`${PREFIX}__indent-city`}>
          {cityCodes.map(code => {
            return (
              <div key={code} className={`${PREFIX}__indent-city__item`}>
                {CITY_CODE_TO_NAME_MAP.get(code)}
                <Image
                  mode="aspectFit"
                  className={`${PREFIX}__indent-city__delete-icon`}
                  src={require('@/statics/svg/circle-delete.svg')}
                  onClick={() => handleDeleteCity(code)}
                />
              </div>
            );
          })}
          {cityCodes.length < 3 && (
            <div className={`${PREFIX}__indent-city__item`} onClick={handleClickAddCity}>
              <Image
                mode="aspectFit"
                className={`${PREFIX}__indent-city__add-icon`}
                src={require('@/statics/svg/add.svg')}
              />
            </div>
          )}
        </div>
      </BlFormItem>
      <BlFormItem title="工作类型">
        <BlFormRadioGroup direction="horizontal" value={employType} onChange={handleEmployTypeChange}>
          <BlFormRadio name={EmployType.Full} text={EMPLOY_TYPE_TITLE_MAP[EmployType.Full]} value={employType} />
          <BlFormRadio name={EmployType.Part} text={EMPLOY_TYPE_TITLE_MAP[EmployType.Part]} value={employType} />
          <BlFormRadio name={EmployType.All} text={EMPLOY_TYPE_TITLE_MAP[EmployType.All]} value={employType} />
        </BlFormRadioGroup>
      </BlFormItem>
      {isFullTimePriceRequired(employType) &&
        (<BlFormItem title="期望全职薪资">
          <BlFormSelect
            title="期望全职薪资"
            value={fullSalary}
            options={FULL_PRICE_OPTIONS}
            onSelect={handleSelectFullSalary}
          />
        </BlFormItem>)}
      {isPartTimePriceRequired(employType) &&
        (<BlFormItem title="期望兼职薪资">
          <BlFormSelect
            title="期望兼职薪资"
            value={partSalary}
            options={PART_PRICE_OPTIONS}
            onSelect={handleSelectPartSalary}
          />
        </BlFormItem>)}
      <BlFormItem title="是否接受坐班">
        <BlFormRadioGroup direction="horizontal" value={acceptWorkForSit} onChange={handleAcceptSittingChange}>
          <BlFormRadio name text="接受" value={acceptWorkForSit} />
          <BlFormRadio name={false} text="不接受" value={acceptWorkForSit} />
        </BlFormRadioGroup>
      </BlFormItem>
    </div>
  );
}

export default forwardRef(ProfileIntentionFragment);
