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

import { Dialog } from '@taroify/core';
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 { JoinGroupHint } from '@/components/join-group-hint';
import LoginButton from '@/components/login-button';
import PageLoading from '@/components/page-loading';
import { PrejobPopup } from '@/components/prejob-popup';
import ProductJobContactDialog from '@/components/product-dialog/job-contact';
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
import { EventName, PageUrl, RoleType } from '@/constants/app';
import { CertificationStatusType } from '@/constants/company';
import { ReportEventId } from '@/constants/event';
import { EMPLOY_TYPE_TITLE_MAP, GET_CONTACT_TYPE, JobManageStatus } from '@/constants/job';
import { ProductType } from '@/constants/product';
import useInviteCode from '@/hooks/use-invite-code';
import { usePublishJob } from '@/hooks/use-publish-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 { GetProductIsUnlockResponse, ProductInfo } from '@/types/product';
import { switchRoleType } from '@/utils/app';
import { copy, logWithPrefix } from '@/utils/common';
import { reportEvent } from '@/utils/event';
import { getJobSalary, getJobTitle, requestJobDetail } from '@/utils/job';
import { calcDistance, isValidLocation } from '@/utils/location';
import { requestProfileDetail } from '@/utils/material';
import { isChatWithSelf, postCreateChat } from '@/utils/message';
import { getInviteCodeFromQueryAndUpdate } from '@/utils/partner';
import { requestProductBalance, requestProductUseRecord } from '@/utils/product';
import { getJumpUrl, getPageQuery, navigateTo } from '@/utils/route';
import { getCommonShareMessage } from '@/utils/share';
import { formatDate } from '@/utils/time';
import Toast from '@/utils/toast';
import { isNeedPhone } 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 [showJobContactDialog, setShowJobContactDialog] = useState(false);
  const [showMaterialGuide, setShowMaterialGuide] = useState(false);
  const [productInfo, setProductInfo] = useState<undefined | ProductInfo>();
  const [productRecord, setProductRecord] = useState<undefined | GetProductIsUnlockResponse>();
  const userInfo = useUserInfo();
  const needPhone = isNeedPhone(userInfo);

  const getProductRecord = useCallback(async () => {
    const result = await requestProductUseRecord(ProductType.VIP, { jobId: data.id });
    setProductRecord(result);
  }, [data.id]);

  const getProductBalance = useCallback(async (loading?: boolean) => {
    if (loading) {
      Taro.showLoading();
    }
    const [, resp] = await requestProductBalance(ProductType.VIP);
    setProductInfo(resp);
    console.log(resp);
    if (loading) {
      Taro.hideLoading();
    }
    return resp;
  }, []);

  const handleClickContact = useCallback(async () => {
    log('handleClickContact');
    if (!data) {
      return;
    }
    reportEvent(ReportEventId.CLICK_JOB_CONTACT);

    try {
      if (data.isAuthed) {
        const toUserId = data.userId;
        if (isChatWithSelf(toUserId)) {
          Toast.error('不能与自己聊天');
          return;
        }
        const chat = await postCreateChat(toUserId);
        let materialMessage: null | IMaterialMessage = null;
        if (!!productInfo?.isCreateResume) {
          const profile = await requestProfileDetail();
          if (profile) {
            materialMessage = {
              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,
          initText: !materialMessage,
          material: materialMessage,
          jobId: data.id,
        });
      } else {
        // Show material guide if no resume and no VIP and no free balance
        if (!productRecord && !productInfo?.isCreateResume && !productInfo?.isPaidVip && !productInfo?.freeBalance) {
          setShowMaterialGuide(true);
          return;
        }
        // Open integrated dialog - it handles buy + contact internally
        setShowJobContactDialog(true);
      }
    } catch (error) {
      const e = error as HttpError;
      const errorCode = e.errorCode;
      if (errorCode === RESPONSE_ERROR_CODE.INSUFFICIENT_BALANCE) {
        setErrorTips('今日开聊次数已用完，请明日再来');
      } else {
        Toast.error('请求失败请重试');
      }
    }
  }, [data, productInfo?.freeBalance, productInfo?.isCreateResume, productInfo?.isPaidVip]);

  const handleDialogClose = useCallback(() => {
    setShowJobContactDialog(false);
    // Refresh data after dialog closes
    getProductRecord();
  }, [getProductRecord]);

  const handleConfirmPrejob = useCallback(
    (type: GET_CONTACT_TYPE) => {
      setShowMaterialGuide(false);
      if (GET_CONTACT_TYPE.VIP === type) {
        getProductBalance().then(() => {
          setShowJobContactDialog(true);
        });
      }
    },
    [getProductBalance]
  );

  // const unAuthedButtonText = useMemo(() => {
  //   if (haveSeen) {
  //     return '查看联系方式';
  //   }
  //
  //   if (productInfo?.isPaidVip) {
  //     return '您是会员，可直接查看';
  //   }
  //
  //   if (productInfo?.freeBalance) {
  //     return `还剩${productInfo.freeBalance}次查看次数`;
  //   }
  //
  //   return productInfo?.isCreateResume? '升级会员即可查看': '创建模卡，免费查看';
  // }, [productInfo, haveSeen]);

  const handleRefresh = useCallback(async () => {
    await getProductBalance(true);
  }, [getProductBalance]);

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

  useEffect(() => {
    getProductBalance();
  }, [getProductBalance]);

  useEffect(() => {
    getProductRecord();
  }, [getProductRecord]);

  return (
    <>
      <div className={`${PREFIX}__footer`}>
        <Button className={`${PREFIX}__share-button`} openType="share">
          分享
        </Button>
        <LoginButton
          needRefresh
          onRefresh={handleRefresh}
          className={`${PREFIX}__contact-publisher`}
          onClick={handleClickContact}
        >
          {data.isAuthed ? '在线沟通' : '查看联系方式'}
          {needPhone ? (
            <div className={`${PREFIX}__contact-publisher-tag`}>登录后可免费报单</div>
          ) : !productRecord && (data.isAuthed || productInfo?.content) ? (
            <div className={`${PREFIX}__contact-publisher-tag`}>
              {data.isAuthed ? '急招岗位可免费查看' : productInfo?.content}
            </div>
          ) : null}
        </LoginButton>
      </div>
      <div>
        {showJobContactDialog && (
          <ProductJobContactDialog
            data={data}
            productRecord={productRecord}
            productInfo={productInfo}
            onRefreshBalance={getProductBalance}
            onClose={handleDialogClose}
          />
        )}
        {showMaterialGuide && (
          <PrejobPopup
            isCreateResume={productInfo?.isCreateResume}
            onCancel={() => setShowMaterialGuide(false)}
            onConfirm={handleConfirmPrejob}
          />
        )}
        <CommonDialog
          content={errorTips}
          confirm="确定"
          visible={!!errorTips}
          onClose={() => setErrorTips('')}
          onClick={() => setErrorTips('')}
        />
      </div>
    </>
  );
};

const CompanyFooter = (props: { data: JobDetails }) => {
  const { data } = props;
  const [showBuy, setShowBuy, handlePublishJob] = usePublishJob(data.id);

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

  return (
    <>
      <div className={`${PREFIX}__footer`}>
        <Button className={`${PREFIX}__share-button`} onClick={handleClickEdit}>
          编辑
        </Button>
        <Button
          disabled={data.status === JobManageStatus.Open}
          className={`${PREFIX}__contact-publisher`}
          onClick={handlePublishJob}
        >
          发布通告
        </Button>
      </div>
      <Dialog open={showBuy} onClose={() => setShowBuy(false)}>
        <Dialog.Content>
          <CompanyPublishJobBuy onNext={handlePublishJob} />
        </Dialog.Content>
      </Dialog>
    </>
  );
};

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 inviteCode = useInviteCode();

  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'> & { c: string; share: string }>();

    if (query?.share === 'true') {
      switchRoleType(RoleType.Anchor);
    }
    getInviteCodeFromQueryAndUpdate(query);
    const jobId = query?.id;
    if (!jobId) {
      return;
    }
    Taro.eventCenter.trigger(EventName.VIEW_JOB_SUCCESS, jobId);
    try {
      const res = await requestJobDetail(jobId);
      setData(res);
    } catch (e) {
      console.error(e);
      Toast.error('出错了，请重试');
    }
  });
  Taro.showShareMenu({
    withShareTicket: true,
  });
  useShareAppMessage(() => {
    if (!data) {
      return getCommonShareMessage({ inviteCode });
    }

    return {
      title: getJobTitle(data) || '',
      path: getJumpUrl(PageUrl.JobDetail, { id: data.id, share: true, c: inviteCode }),
    };
  });

  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>

        {!isOwner && <JoinGroupHint />}

        <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>
  );
}
