import { Map, MapProps, Text, Image, Button } from '@tarojs/components';
import Taro, { useLoad, useShareAppMessage } from '@tarojs/taro';

import React, { useCallback, useEffect, useState } from 'react';

import { CertificationStatusIcon } from '@/components/certification-status';
import CommonDialog from '@/components/common-dialog';
import DevDiv from '@/components/dev-div';
import JobRecommendList from '@/components/job-recommend-list';
import LoginButton from '@/components/login-button';
import MaterialGuide from '@/components/material-guide';
import PageLoading from '@/components/page-loading';
import ProductJobDialog from '@/components/product-dialog/job';
import { RoleType, EventName, PageUrl } from '@/constants/app';
import { CertificationStatusType } from '@/constants/company';
import { CollectEventName, ReportEventId } from '@/constants/event';
import { EMPLOY_TYPE_TITLE_MAP } from '@/constants/job';
import useUserInfo from '@/hooks/use-user-info';
import useRoleType from '@/hooks/user-role-type';
import { RESPONSE_ERROR_CODE } from '@/http/constant';
import { HttpError } from '@/http/error';
import { JobDetails } from '@/types/job';
import { IMaterialMessage } from '@/types/message';
import { copy, logWithPrefix } from '@/utils/common';
import { collectEvent, reportEvent } from '@/utils/event';
import { getJobTitle, getJobSalary, postPublishJob, requestJobDetail } from '@/utils/job';
import { calcDistance, isValidLocation } from '@/utils/location';
import { requestProfileDetail } from '@/utils/material';
import { isChatWithSelf, postCreateChat } from '@/utils/message';
import { getJumpUrl, getPageQuery, navigateTo } from '@/utils/route';
import { getCommonShareMessage } from '@/utils/share';
import { formatDate } from '@/utils/time';
import Toast from '@/utils/toast';
import { isNeedCreateMaterial } from '@/utils/user';

import './index.less';

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

const getMapCallout = (data: JobDetails): MapProps.callout | undefined => {
  if (!data.jobLocation?.address) {
    return;
  }
  return {
    display: 'ALWAYS',
    content: data.jobLocation.address,
    color: '#000000',
    bgColor: '#FFFFFF',
    fontSize: 12,
    textAlign: 'center',
    anchorX: 0,
    anchorY: 0,
    borderRadius: 4,
    borderWidth: 0,
    borderColor: '#FFFFFF',
    padding: 4,
  };
};

const AnchorFooter = (props: { data: JobDetails }) => {
  const { data } = props;
  const [errorTips, setErrorTips] = useState<string>('');
  const [dialogVisible, setDialogVisible] = useState(false);
  const [showMaterialGuide, setShowMaterialGuide] = useState(false);

  const handleClickContact = useCallback(async () => {
    log('handleClickContact');
    if (!data) {
      return;
    }
    reportEvent(ReportEventId.CLICK_JOB_CONTACT);
    try {
      const needCreateMaterial = await isNeedCreateMaterial();
      if (needCreateMaterial) {
        setShowMaterialGuide(true);
        return;
      }
      if (data.isAuthed) {
        const toUserId = data.userId;
        if (isChatWithSelf(toUserId)) {
          Toast.error('不能与自己聊天');
          return;
        }
        const profile = await requestProfileDetail();
        const chat = await postCreateChat(toUserId);
        const materialMessage: IMaterialMessage = {
          id: profile.id,
          name: profile.name,
          age: profile.age,
          height: profile.height,
          weight: profile.weight,
          shoeSize: profile.shoeSize,
          gender: profile.gender,
          workedSecCategoryStr: profile.workedSecCategoryStr,
        };
        navigateTo(PageUrl.MessageChat, { chatId: chat.chatId, material: materialMessage, jobId: data.id });
      } else {
        setDialogVisible(true);
      }
    } catch (error) {
      const e = error as HttpError;
      const errorCode = e.errorCode;
      if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_BALANCE) {
        setErrorTips('今日开聊次数已用完，请明日再来');
      } else {
        Toast.error('请求失败请重试');
      }
    }
  }, [data]);

  const handleDialogHidden = useCallback(() => setDialogVisible(false), []);

  return (
    <>
      <div className={`${PREFIX}__footer`}>
        <Button className={`${PREFIX}__share-button`} openType="share">
          分享
        </Button>
        <LoginButton className={`${PREFIX}__contact-publisher`} onClick={handleClickContact}>
          {data.isAuthed ? '在线沟通' : '立即联系'}
        </LoginButton>
      </div>
      <div>
        {dialogVisible && <ProductJobDialog data={data} onClose={handleDialogHidden} />}
        {showMaterialGuide && <MaterialGuide onClose={() => setShowMaterialGuide(false)} />}
        <CommonDialog
          content={errorTips}
          confirm="确定"
          visible={!!errorTips}
          onClose={() => setErrorTips('')}
          onClick={() => setErrorTips('')}
        />
      </div>
    </>
  );
};

const CompanyFooter = (props: { data: JobDetails }) => {
  const { data } = props;

  const handleClickEdit = useCallback(() => navigateTo(PageUrl.JobPublish, { jobId: data.id }), [data]);

  const handlePublishJob = useCallback(async () => {
    try {
      Taro.showLoading();
      await postPublishJob(data.id);
      Taro.eventCenter.trigger(EventName.COMPANY_JOB_PUBLISH_CHANGED);
      Toast.success('发布成功');
      Taro.hideLoading();
    } catch (error) {
      Taro.hideLoading();
      const e = error as HttpError;
      const errorCode = e.errorCode;
      collectEvent(CollectEventName.PUBLISH_OPEN_JOB_FAILED, { jobId: data.id, error: e.info?.() || e.message });
      if (errorCode === RESPONSE_ERROR_CODE.BOSS_VIP_EXPIRED) {
        Toast.info('该通告已到期，请创建新通告', 3000);
      } else {
        Toast.error(e.message || '发布失败请重试', 3000);
      }
      console.error(e);
    }
  }, [data]);

  return (
    <>
      <div className={`${PREFIX}__footer`}>
        <Button className={`${PREFIX}__share-button`} onClick={handleClickEdit}>
          编辑
        </Button>
        <Button className={`${PREFIX}__contact-publisher`} onClick={handlePublishJob}>
          发布通告
        </Button>
      </div>
    </>
  );
};

export default function JobDetail() {
  const roleType = useRoleType();
  const userInfo = useUserInfo();
  const [data, setData] = useState<JobDetails | null>(null);
  const isOwner = roleType === RoleType.Company && userInfo.userId === data?.userId;

  const onDev = useCallback(async () => data && copy(data.id), [data]);

  const handleClickMap = useCallback(
    (e: React.MouseEvent) => {
      e.stopPropagation();

      if (!data?.jobLocation) {
        return;
      }
      Taro.openLocation({
        longitude: Number(data.jobLocation.longitude),
        latitude: Number(data.jobLocation.latitude),
        address: data.jobLocation.address,
      });
    },
    [data]
  );

  useEffect(() => {
    const callback = async (jobId: string) => {
      try {
        const res = await requestJobDetail(jobId);
        setData(res);
      } catch (e) {
        console.error(e);
      }
    };
    Taro.eventCenter.on(EventName.JOB_UPDATE, callback);
    return () => {
      Taro.eventCenter.off(EventName.JOB_UPDATE, callback);
    };
  }, []);

  useLoad(async () => {
    const query = getPageQuery<Pick<JobDetails, 'id'>>();
    const jobId = query?.id;
    if (!jobId) {
      return;
    }
    try {
      const res = await requestJobDetail(jobId);
      setData(res);
    } catch (e) {
      console.error(e);
      Toast.error('出错了，请重试');
    }
  });

  useShareAppMessage(() => {
    if (!data) {
      return getCommonShareMessage();
    }
    return {
      title: getJobTitle(data) || '',
      path: getJumpUrl(PageUrl.JobDetail, { id: data.id, share: true }),
    };
  });

  if (!data) {
    return <PageLoading />;
  }

  return (
    <div className={PREFIX}>
      <div className={`${PREFIX}__container`}>
        <div className={`${PREFIX}__header`}>
          <div className={`${PREFIX}__header-info`}>
            <DevDiv className={`${PREFIX}__header-title`} OnDev={onDev}>
              {getJobTitle(data)}
            </DevDiv>
            <div className={`${PREFIX}__employ-type`}>{EMPLOY_TYPE_TITLE_MAP[data.employType]}</div>
          </div>
          <div className={`${PREFIX}__salary`}>{getJobSalary(data)}</div>
          <div className={`${PREFIX}__update-time`}>{`${formatDate(data.updated)}更新`}</div>
          <div className={`${PREFIX}__tips`}>请注意甄别通告真假，谨防上当</div>
          <div className={`${PREFIX}__publisher`}>
            <div className={`${PREFIX}__publisher-name`}>{`发布人：${data.publisher}`}</div>
            {data.isAuthed && (
              <CertificationStatusIcon
                className={`${PREFIX}__certification-type`}
                status={CertificationStatusType.Success}
                small
              />
            )}
            <Image
              mode="aspectFit"
              className={`${PREFIX}__publisher-avatar`}
              src={data.publisherAvatar || require('@/statics/svg/wechat.svg')}
            />
          </div>
          {data.companyName && <div className={`${PREFIX}__company`}>{`公司：${data.companyName}`}</div>}
        </div>

        <div className={`${PREFIX}__content`}>
          <div className={`${PREFIX}__content-title`}>职位描述</div>
          <div className={`${PREFIX}__tags`}>
            {(data.tags || []).map((keyword: string, index) => (
              <div className={`${PREFIX}__tag`} key={index}>
                {keyword}
              </div>
            ))}
          </div>
          <Text className={`${PREFIX}__description`}>{data.sourceText}</Text>
          <div className={`${PREFIX}__address-wrapper`}>
            <Image className={`${PREFIX}__distance-icon`} src={require('@/statics/svg/location.svg')} />
            <div className={`${PREFIX}__detailed-address`}>{data.jobLocation?.address}</div>
          </div>
          {data.distance && (
            <div className={`${PREFIX}__distance-wrapper`}>
              <Image className={`${PREFIX}__distance-icon`} src={require('@/statics/svg/location.svg')} />
              <div className={`${PREFIX}__distance`}>{calcDistance(data.distance)}</div>
            </div>
          )}
          {isValidLocation(data.jobLocation) && (
            <div className={`${PREFIX}__map__wrapper`} onClick={handleClickMap}>
              <Map
                enableZoom={false}
                enableScroll={false}
                className={`${PREFIX}__map`}
                latitude={Number(data.jobLocation.latitude)}
                longitude={Number(data.jobLocation.longitude)}
                markers={[
                  {
                    id: 0,
                    latitude: Number(data.jobLocation.latitude),
                    longitude: Number(data.jobLocation.longitude),
                    callout: getMapCallout(data),
                    iconPath: '',
                    width: 20,
                    height: 36,
                  },
                ]}
                onError={() => Toast.error('地图加载错误')}
              />
              <div className={`${PREFIX}__map__mask`} onClick={handleClickMap} />
            </div>
          )}
        </div>
        {!isOwner && <JobRecommendList />}
        <div className={`${PREFIX}__bottom-space`} />
      </div>
      {!isOwner && <AnchorFooter data={data} />}
      {isOwner && <CompanyFooter data={data} />}
    </div>
  );
}
