import { BaseEventOrig, Image, Swiper, SwiperItem, SwiperProps } from '@tarojs/components';
import Taro from '@tarojs/taro';

import classNames from 'classnames';
import { useCallback, useState } from 'react';

import DevDiv from '@/components/dev-div';
import SafeBottomPadding from '@/components/safe-bottom-padding';
import { OpenSource, PageUrl } from '@/constants/app';
import { CITY_CODE_TO_NAME_MAP } from '@/constants/city';
import { FULL_PRICE_OPTIONS, PART_PRICE_OPTIONS } from '@/constants/job';
import { ProfileGroupType, ProfileTitleMap, WORK_YEAR_OPTIONS } from '@/constants/material';
import { MaterialProfile } from '@/types/material';
import { logWithPrefix, isDesktop } from '@/utils/common';
import { getBasicInfo, sortVideos } from '@/utils/material';
import { navigateTo } from '@/utils/route';

import './index.less';
import onChangeEventDetail = SwiperProps.onChangeEventDetail;

interface IProps {
  editable: boolean;
  profile: MaterialProfile;
  onDev?: () => void;
}

const PREFIX = 'profile-view-fragment';
const log = logWithPrefix(PREFIX);
const DEFAULT_TEXT = '未填写';

const getIndentCity = (codeString: string = '') => {
  const codes = codeString.split('、');
  const cityNames: string[] = [];
  codes.forEach(code => {
    const cityName = CITY_CODE_TO_NAME_MAP.get(code);
    cityName && cityNames.push(cityName);
  });
  return cityNames.join('、');
};

const getIndentPrice = (min: number, max: number, full: boolean) => {
  if (!min && !max) {
    return DEFAULT_TEXT;
  }
  const options = full ? FULL_PRICE_OPTIONS : PART_PRICE_OPTIONS;
  const option = options.find(o => o.value.minSalary === min && o.value.maxSalary === max);
  if (option) {
    return option.label;
  }

  const unit = full ? 'K' : '';
  const prices: string[] = [];
  min && prices.push(`${full ? Number(min) / 1000 : min}${unit}`);
  max && prices.push(`${full ? Number(max) / 1000 : max}${unit}`);
  return prices.join(' - ');
};

const getWorkYear = (year: number) => {
  if (!year) {
    return DEFAULT_TEXT;
  }
  const y = Math.min(year, 3);
  return WORK_YEAR_OPTIONS.find(option => option.value === y)?.label || `${y}年`;
};

const getDataGroup = (profile: MaterialProfile | null) => {
  if (!profile) {
    return [];
  }
  return [
    {
      title: ProfileTitleMap[ProfileGroupType.Intention],
      type: ProfileGroupType.Intention,
      items: [
        { title: '全职薪资', value: getIndentPrice(profile.fullTimeMinPrice, profile.fullTimeMaxPrice, true) || '' },
        { title: '兼职薪资', value: getIndentPrice(profile.partyTimeMinPrice, profile.partyTimeMaxPrice, false) || '' },
        { title: '意向城市', value: getIndentCity(profile.cityCodes) || DEFAULT_TEXT },
        { title: '是否接受坐班', value: profile.acceptWorkForSit ? '是' : '否' },
      ],
    },
    {
      title: ProfileTitleMap[ProfileGroupType.Experience],
      type: ProfileGroupType.Experience,
      items: [
        { title: '直播年限', value: getWorkYear(profile.workedYear) || DEFAULT_TEXT },
        { title: '直播过的账号', value: profile.workedAccounts || DEFAULT_TEXT },
        { title: '自然流起号经验', value: Boolean(profile.newAccountExperience) ? '有' : '无' },
        { title: '直播过的品类', value: profile.workedSecCategoryStr || DEFAULT_TEXT },
        { title: '最高GMV', value: profile.maxGmv ? `${profile.maxGmv / 10000}万` : DEFAULT_TEXT },
        { title: '最高在线人数', value: profile.maxOnline || DEFAULT_TEXT },
      ],
    },
    {
      title: ProfileTitleMap[ProfileGroupType.Advantages],
      type: ProfileGroupType.Advantages,
      items: [{ title: '自身优势', value: profile.advantages || DEFAULT_TEXT, fullLine: true }],
    },
  ];
};

export default function ProfileViewFragment(props: IProps) {
  const { profile, editable, onDev } = props;
  const [coverIndex, setCoverIndex] = useState(0);
  const dataGroup = getDataGroup(profile);
  const videos = sortVideos(profile?.materialVideoInfoList || []);

  const handleClickVideo = useCallback(
    (index: number) => {
      log('handleClickVideo', index);

      if (isDesktop) {
        navigateTo(PageUrl.MaterialWebview, {
          source: encodeURIComponent(videos[index].url),
        });
      } else {
        Taro.previewMedia({
          sources: videos.map(video => ({ url: video.url, type: video.type })),
          current: index,
        });
      }
    },
    [videos]
  );

  const handleEditVideo = useCallback(() => {
    log('handleEditBasic');
    navigateTo(PageUrl.MaterialUploadVideo, { source: OpenSource.UserPage });
  }, []);

  const handleEditBasic = useCallback(() => {
    log('handleEditBasic');
    navigateTo(PageUrl.MaterialEditProfile, { type: ProfileGroupType.Basic });
  }, []);

  const handleEditGroupItem = useCallback((groupType: ProfileGroupType) => {
    log('handleEditGroupItem', groupType);
    navigateTo(PageUrl.MaterialEditProfile, { type: groupType });
  }, []);

  const videoLength = videos.length ? videos.length : 0;
  const showSwiperButton = videoLength > 1 && isDesktop;

  const handleChange = useCallback((e: BaseEventOrig<onChangeEventDetail>) => {
    setCoverIndex(e.detail.current);
  }, []);

  const handlePrev = useCallback(() => {
    setCoverIndex(coverIndex ? coverIndex - 1 : videoLength - 1);
  }, [coverIndex, videoLength]);

  const handleNext = useCallback(() => {
    setCoverIndex(coverIndex === videoLength - 1 ? 0 : coverIndex + 1);
  }, [coverIndex, videoLength]);

  return (
    <div className={PREFIX}>
      <div className={`${PREFIX}__header`}>
        <Swiper className={`${PREFIX}__header__swiper`} current={coverIndex} onChange={handleChange} circular>
          {videos.map((cover, index) => (
            <SwiperItem key={cover.coverUrl}>
              <div className={`${PREFIX}__header__swiper-item`}>
                <Image
                  mode="aspectFill"
                  src={cover.coverUrl}
                  className={`${PREFIX}__header__cover`}
                  onClick={() => handleClickVideo(index)}
                />
                {cover.type === 'video' && (
                  <Image
                    className={`${PREFIX}__header__cover-preview`}
                    mode="aspectFit"
                    src={require('@/statics/svg/preview_video.svg')}
                    onClick={() => handleClickVideo(index)}
                  />
                )}
              </div>
            </SwiperItem>
          ))}
        </Swiper>
        {showSwiperButton && (
          <div className={`${PREFIX}__header__swiper-button__prev`} onClick={handlePrev}>
            <Image
              className={`${PREFIX}__header__swiper-button__image`}
              mode="aspectFit"
              src={require('@/statics/svg/arrow-left-thin.svg')}
            />
          </div>
        )}
        {showSwiperButton && (
          <div className={`${PREFIX}__header__swiper-button__next`} onClick={handleNext}>
            <Image
              className={`${PREFIX}__header__swiper-button__image`}
              mode="aspectFit"
              src={require('@/statics/svg/arrow-right-thin.svg')}
            />
          </div>
        )}
        {editable && (
          <div className={`${PREFIX}__header__edit-video`} onClick={handleEditVideo}>
            编辑录屏
          </div>
        )}
        <div className={`${PREFIX}__header__banner`}>
          <div>{videos[coverIndex]?.title || ''}</div>
          <div
            className={`${PREFIX}__header__video-size`}
          >{`${coverIndex + 1}/${profile.materialVideoInfoList.length}`}</div>
        </div>
      </div>
      <div className={`${PREFIX}__body`}>
        <div className={`${PREFIX}__basic-info`}>
          <div className={`${PREFIX}__basic-info__name-container`}>
            <DevDiv className={`${PREFIX}__basic-info__name`} OnDev={onDev}>
              {profile.name}
            </DevDiv>
            {editable && (
              <div className={`${PREFIX}__basic-info__edit`} onClick={handleEditBasic}>
                编辑
              </div>
            )}
          </div>
          <div className={`${PREFIX}__basic-info__content`}>{getBasicInfo(profile)}</div>
          <div className={`${PREFIX}__divider`} />
        </div>
        {dataGroup.map((data, index: number) => (
          <div className={`${PREFIX}__info-group`} key={data.type}>
            <div className={`${PREFIX}__info-group__header`}>
              {index ? (
                <div className={`${PREFIX}__info-group__header__title`}>{data.title}</div>
              ) : (
                <DevDiv className={`${PREFIX}__info-group__header__title`} OnDev={onDev}>{data.title}</DevDiv>
              )}
              {editable && (
                <div className={`${PREFIX}__info-group__header__edit`} onClick={() => handleEditGroupItem(data.type)}>
                  编辑
                </div>
              )}
            </div>
            <div className={`${PREFIX}__info-group__items`}>
              {data.items.map(item => (
                <div
                  key={String(item.value)}
                  className={classNames(`${PREFIX}__info-group__item`, { 'full-line': item.fullLine })}
                >
                  <div className={`${PREFIX}__info-group__item__title`}>{item.title}</div>
                  <div className={`${PREFIX}__info-group__item__value`}>{item.value}</div>
                </div>
              ))}
            </div>
            {index !== dataGroup.length - 1 && <div className={`${PREFIX}__divider`} />}
          </div>
        ))}
      </div>
      <SafeBottomPadding />
    </div>
  );
}
