import Taro, { useDidShow, useLoad, useShareAppMessage } from '@tarojs/taro';

import { Tabs } from '@taroify/core';
import { useCallback, useEffect, useRef, useState } from 'react';

import HomePage from '@/components/home-page';
import LocationDialog from '@/components/location-dialog';
import { LoginGuide } from '@/components/login-guide';
import MaterialGuide from '@/components/material-guide';
import { EventName, OpenSource, PageUrl } from '@/constants/app';
import { EmployType, JOB_PAGE_TABS, SortType } from '@/constants/job';
import JobFragment from '@/fragments/job/base';
import useLocation from '@/hooks/use-location';
import useNavigation from '@/hooks/use-navigation';
import { Coordinate } from '@/types/location';
import { logWithPrefix } from '@/utils/common';
import { getWxLocation, isNotNeedAuthorizeLocation, requestLocation } from '@/utils/location';
import { requestUnreadMessageCount } from '@/utils/message';
import { getJumpUrl, getPageQuery, navigateTo } from '@/utils/route';
import { getCommonShareMessage } from '@/utils/share';
import Toast from '@/utils/toast';
import { isNeedCreateMaterial } from '@/utils/user';

import './index.less';

const PREFIX = 'job';
const log = logWithPrefix(PREFIX);

export default function Job() {
  const location = useLocation();
  const { barHeight, statusBarHeight } = useNavigation();
  const [tabType, setTabType] = useState<EmployType>(EmployType.All);
  const [sortType, setSortType] = useState<SortType>(SortType.RECOMMEND);
  const [cityCode, setCityCode] = useState<string>(location.cityCode);
  const [coordinate, setCoordinate] = useState<Coordinate>({
    latitude: location.latitude,
    longitude: location.longitude,
  });
  const [showMaterialGuide, setShowMaterialGuide] = useState(false);
  const [showAuthorize, setShowAuthorize] = useState(false);
  const cityValuesChangedRef = useRef(false);

  const handleTypeChange = useCallback(value => setTabType(value), []);

  const handleClickCity = useCallback(
    () => navigateTo(PageUrl.CitySearch, { city: cityCode, source: OpenSource.JobPage }),
    [cityCode]
  );

  const handleClickSortType = useCallback(
    async (type: SortType) => {
      if (type === SortType.DISTANCE && (!location.latitude || !location.longitude)) {
        const res = await getWxLocation();
        if (!res) {
          Toast.info('获取位置信息失败，请重试');
          return;
        }
        const { latitude, longitude } = res;
        setCoordinate({ latitude, longitude });
      }
      setSortType(type);
    },
    [location]
  );

  const handleCityChange = useCallback(data => {
    log('handleCityChange', data);
    const { openSource, cityCode: code } = data;
    if (openSource !== OpenSource.JobPage) {
      return;
    }
    cityValuesChangedRef.current = true;
    setCityCode(code);
  }, []);

  const handleAfterBindPhone = useCallback(async () => {
    if (await isNeedCreateMaterial()) {
      setShowMaterialGuide(true);
    }
  }, []);

  const handleCloseAuthorize = useCallback(() => setShowAuthorize(false), []);

  const handleClickAuthorize = useCallback(() => {
    requestLocation(true);
    setShowAuthorize(false);
  }, []);

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

  useEffect(() => {
    if (cityValuesChangedRef.current) {
      return;
    }
    setCityCode(location.cityCode);
  }, [location]);

  useLoad(async () => {
    const query = getPageQuery<{ sortType: SortType }>();
    const type = query.sortType;
    if (type === SortType.CREATE_TIME) {
      setSortType(type);
    }
    if (await isNotNeedAuthorizeLocation()) {
      log('not need authorize location');
      requestLocation();
    } else {
      log('show authorize location dialog');
      setShowAuthorize(true);
    }
  });

  useDidShow(() => requestUnreadMessageCount());

  useShareAppMessage(() => {
    if (sortType === SortType.CREATE_TIME) {
      return {
        title: '这里有今日全城新增通告，快来看看',
        path: getJumpUrl(PageUrl.Job, { sortType }),
      };
    }
    return getCommonShareMessage();
  });

  return (
    <HomePage>
      <Tabs
        swipeable
        value={tabType}
        className={`${PREFIX}__tabs`}
        onChange={handleTypeChange}
        style={{ height: barHeight.current, paddingTop: statusBarHeight.current }}
      >
        {JOB_PAGE_TABS.map(tab => (
          <Tabs.TabPane value={tab.type} title={tab.title} key={tab.type}>
            <JobFragment
              cityCode={cityCode}
              sortType={sortType}
              employType={tab.type}
              coordinate={coordinate}
              onClickCity={handleClickCity}
              onClickSort={handleClickSortType}
            />
          </Tabs.TabPane>
        ))}
      </Tabs>
      <div>
        <LocationDialog open={showAuthorize} onClose={handleCloseAuthorize} onClick={handleClickAuthorize} />
        <LoginGuide disabled={showAuthorize} onAfterBind={handleAfterBindPhone} />
        {showMaterialGuide && <MaterialGuide onClose={() => setShowMaterialGuide(false)} />}
      </div>
    </HomePage>
  );
}
