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

import { Fragment, useCallback, useEffect, useRef, useState } from 'react';

import SafeBottomPadding from '@/components/safe-bottom-padding';
import { EventName } from '@/constants/app';
import { CollectEventName } from '@/constants/event';
import { ProfileGroupType, ProfileTitleMap } from '@/constants/material';
import ProfileAdvantagesFragment from '@/fragments/profile/advantages';
import ProfileBasicFragment from '@/fragments/profile/basic';
import ProfileExperienceFragment from '@/fragments/profile/experience';
import ProfileIntentionFragment from '@/fragments/profile/intention';
import useLocation from '@/hooks/use-location';
import { MaterialProfile } from '@/types/material';
import { logWithPrefix } from '@/utils/common';
import { collectEvent } from '@/utils/event';
import { isFullTimePriceRequired, isPartTimePriceRequired } from '@/utils/job';
import { updateProfile, subscribeMaterialMessage } from '@/utils/material';
import { navigateBack } from '@/utils/route';
import Toast from '@/utils/toast';

import './index.less';
import ProfileOthersFragment from '@/fragments/profile/others';

const PREFIX = 'page-material-create-profile';
const log = logWithPrefix(PREFIX);

const REQUIRE_KEYS = {
  [ProfileGroupType.Basic]: ['name', 'gender', 'age'],
  [ProfileGroupType.Intention]: [
    'cityCodes',
    'employType',
    'fullTimeMinPrice',
    'fullTimeMaxPrice',
    'partyTimeMinPrice',
    'partyTimeMaxPrice',
  ],
  [ProfileGroupType.Experience]: [],
  [ProfileGroupType.Advantages]: [],
  [ProfileGroupType.Others]: [],
};

const COULD_SKIP = [ProfileGroupType.Experience, ProfileGroupType.Others];

const CONDITIONAL_REQUIRED_KEYS = {
  [ProfileGroupType.Intention]: [
    ['fullTimeMinPrice', data => isFullTimePriceRequired(data.employType)],
    ['fullTimeMaxPrice', data => isFullTimePriceRequired(data.employType)],
    ['partyTimeMinPrice', data => isPartTimePriceRequired(data.employType)],
    ['partyTimeMaxPrice', data => isPartTimePriceRequired(data.employType)],
  ],
};

const getNextStepGroupType = (curType: ProfileGroupType) => {
  switch (curType) {
    case ProfileGroupType.Basic:
      return ProfileGroupType.Experience;
    case ProfileGroupType.Intention:
      return ProfileGroupType.Basic;
    case ProfileGroupType.Experience:
      return ProfileGroupType.Others;
    case ProfileGroupType.Others:
      return ProfileGroupType.Advantages;
    default:
      return null;
  }
};

const isValidFormData = (type: ProfileGroupType, data: Partial<MaterialProfile>) => {
  const requireKeys = REQUIRE_KEYS[type] || [];
  const conditionalKeys = CONDITIONAL_REQUIRED_KEYS[type] || [];

  const requiredValidator = (key: any) => typeof data[key] !== 'undefined' && data[key] !== '';
  return (
    requireKeys.every(requiredValidator) &&
    conditionalKeys.every(([key, validator]) => {
      return !validator(data) || requiredValidator(key);
    })
  );
};

export default function MaterialCreateProfile() {
  const location = useLocation();
  const [groupType, setGroupType] = useState<ProfileGroupType>(ProfileGroupType.Intention);
  const ref = useRef<{ getData: () => Partial<MaterialProfile> } | null>(null);
  const ProfileFragment =
    groupType === ProfileGroupType.Basic
      ? ProfileBasicFragment
      : groupType === ProfileGroupType.Intention
        ? ProfileIntentionFragment
        : groupType === ProfileGroupType.Experience
          ? ProfileExperienceFragment
          : groupType === ProfileGroupType.Advantages
            ? ProfileAdvantagesFragment
            : groupType === ProfileGroupType.Others
              ? ProfileOthersFragment
              : Fragment;

  const handleSkip = useCallback(() => {
    const nextType = getNextStepGroupType(groupType);
    if (nextType) {
      setGroupType(nextType);
    }
  }, [groupType]);

  const handleSubmit = useCallback(async () => {
    try {
      const data = ref.current?.getData();
      log('handleSubmit data:', data);
      if (!data) {
        throw new Error('数据异常');
      }
      if (!isValidFormData(groupType, data)) {
        Toast.error('重要选项必填!');
        return;
      }

      const nextType = getNextStepGroupType(groupType);
      log('handleSubmit nextType:', nextType);
      if (nextType) {
        await updateProfile(data);
      } else {
        // 发起订阅不能在异步任务中，保证是第一个
        await Promise.all([subscribeMaterialMessage(), updateProfile(data)]);
      }
      Taro.eventCenter.trigger(EventName.CREATE_PROFILE);
      nextType ? setGroupType(nextType) : navigateBack(2);
    } catch (e) {
      Toast.error('保存失败请重试');
      collectEvent(CollectEventName.CREATE_MATERIAL_FAILED, e);
    }
  }, [ref, groupType]);

  useEffect(() => {
    const title = ProfileTitleMap[groupType];
    Taro.setNavigationBarTitle({ title });
  }, [groupType]);

  const couldSkip = COULD_SKIP.includes(groupType);

  return (
    <div className={PREFIX}>
      <ProfileFragment ref={ref} profile={{ cityCodes: location.cityCode || '' }} />
      <SafeBottomPadding />
      <div className={`${PREFIX}__footer`}>
        <Button className={`${PREFIX}__submit-btn ${couldSkip ? 'up' : ''}`} onClick={handleSubmit}>
          {groupType === ProfileGroupType.Advantages ? '完成' : '下一步'}
        </Button>
        {couldSkip && (
          <div className={`${PREFIX}__skip-btn-wrapper`}>
            <div className={`${PREFIX}__skip-btn`} onClick={handleSkip}>
              跳过
            </div>
          </div>
        )}
        <SafeBottomPadding />
      </div>
    </div>
  );
}
