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

import { Cell, Dialog } from '@taroify/core';
import { Fragment, useCallback, useEffect, useState } from 'react';

import PageLoading from '@/components/page-loading';
import { PublishJobQrCodeDialog } from '@/components/product-dialog/publish-job';
import CompanyPublishJobBuy from '@/components/product-dialog/steps-ui/company-publish-job-buy';
import SafeBottomPadding from '@/components/safe-bottom-padding';
import { ISelectOption } from '@/components/select';
import { PageUrl } from '@/constants/app';
import { JobManageStatus } from '@/constants/job';
import { OrderStatus, OrderType, ProductSpecId, ProductType } from '@/constants/product';
import { usePublishJob } from '@/hooks/use-publish-job';
import { BatchPublishGroup } from '@/types/group';
import { logWithPrefix } from '@/utils/common';
import { requestJobDetail } from '@/utils/job';
import {
  getOrderPrice,
  isCancelPay,
  requestAllBuyProduct,
  requestCreatePayInfo,
  requestOrderInfo,
  requestPayment,
} from '@/utils/product';
import { navigateTo } from '@/utils/route';
import Toast from '@/utils/toast';
import './index.less';

interface CityValue extends BatchPublishGroup {
  cityName: string;
}

interface CityOption extends ISelectOption<CityValue> {
  value: CityValue;
}

const PREFIX = 'user-batch-publish';
const log = logWithPrefix(PREFIX);
export const cityValues: CityValue[] = [
  { cityCode: '440100', cityName: '广州', count: 800 },
  { cityCode: '440300', cityName: '深圳', count: 100 },
  { cityCode: '330100', cityName: '杭州', count: 750 },
  { cityCode: '110100', cityName: '北京', count: 150 },
  { cityCode: '510100', cityName: '成都', count: 100 },
  { cityCode: '500100', cityName: '重庆', count: 50 },
  { cityCode: '430100', cityName: '长沙', count: 50 },
  { cityCode: '350200', cityName: '厦门', count: 50 },
  { cityCode: '310100', cityName: '上海', count: 150 },
  { cityCode: '420100', cityName: '武汉', count: 80 },
  { cityCode: '610100', cityName: '西安', count: 60 },
  { cityCode: '410100', cityName: '郑州', count: 150 },
].sort((a, b) => b.count - a.count);
const MIN_GROUP_SIZE = 20;
const GROUP_OPTIONS = [
  { value: MIN_GROUP_SIZE, productSpecId: ProductSpecId.GroupBatchPublish20, label: '20', price: 18 },
  { value: 50, productSpecId: ProductSpecId.GroupBatchPublish50, label: '50', price: 40 },
  { value: 60, productSpecId: ProductSpecId.GroupBatchPublish60, label: '60', price: 48 },
  { value: 80, productSpecId: ProductSpecId.GroupBatchPublish80, label: '80', price: 58 },
  { value: 100, productSpecId: ProductSpecId.GroupBatchPublish100, label: '100', price: 68 },
  { value: 150, productSpecId: ProductSpecId.GroupBatchPublish150, label: '150', price: 98 },
  { value: 300, productSpecId: ProductSpecId.GroupBatchPublish300, label: '300', price: 128 },
  { value: 500, productSpecId: ProductSpecId.GroupBatchPublish500, label: '500', price: 168 },
  { value: 750, productSpecId: ProductSpecId.GroupBatchPublish750, label: '750', price: 188 },
  { value: 800, productSpecId: ProductSpecId.GroupBatchPublish800, label: '800', price: 198 },
  { value: 1000, productSpecId: ProductSpecId.GroupBatchPublish1000, label: '1000', price: 288 },
];

const calcPrice = (city: CityValue | null) => {
  if (!city) {
    return {};
  }
  const { count } = city;
  const originalPrice = count * 1;
  const price = GROUP_OPTIONS.find(o => o.value === count)?.price || 18;
  const productSpecId = GROUP_OPTIONS.find(o => o.value === count)?.productSpecId || ProductSpecId.GroupBatchPublish20;
  return { price, originalPrice, productSpecId };
};

export default function UserBatchPublish({ cityCode, jobId }: { cityCode: string; jobId: string }) {
  const [loading, setLoading] = useState(true);
  const [showQrCode, setShowQrCode] = useState(false);
  const [city, setCity] = useState<CityOption['value'] | null>(null);
  const { price, originalPrice, productSpecId } = calcPrice(city);
  const [showPublishJob, setShowPublishJob] = useState(false);

  const [showBuy, setShowBuy, handlePublishJob] = usePublishJob(jobId);

  const handleClickViewGroup = useCallback(() => navigateTo(PageUrl.GroupList, { city: city?.cityCode }), [city]);

  const handleClickBuy = useCallback(async () => {
    // if (1 < 2) {
    //   await new Promise(r => setTimeout(r, 3000));
    //   setShowQrCode(true);
    //   return;
    // }
    if (!price || !productSpecId) {
      return;
    }
    try {
      Taro.showLoading();
      const allowBuy = await requestAllBuyProduct(ProductType.GroupBatchPublish);
      if (!allowBuy) {
        Taro.hideLoading();
        Toast.info('您最近已购买过，可直接联系客服');
        setShowQrCode(true);
        return;
      }

      const jobDetail = await requestJobDetail(jobId);

      if (jobDetail.status !== JobManageStatus.Open) {
        Taro.hideLoading();
        setShowPublishJob(true);
        return;
      }

      const { payOrderNo, createPayInfo } = await requestCreatePayInfo({
        type: OrderType.GroupBatchPublish,
        amt: getOrderPrice(price),
        // amt: 1,
        productCode: ProductType.GroupBatchPublish,
        productSpecId: productSpecId,
      });
      log('handleBuy payInfo', payOrderNo, createPayInfo);
      await requestPayment({
        timeStamp: createPayInfo.timeStamp,
        nonceStr: createPayInfo.nonceStr,
        package: createPayInfo.packageVal,
        signType: createPayInfo.signType,
        paySign: createPayInfo.paySign,
      });
      const { status } = await requestOrderInfo({ payOrderNo });
      log('handleBuy orderInfo', status);
      if (status !== OrderStatus.Success) {
        throw new Error('order status error');
      }
      Taro.hideLoading();
      setShowQrCode(true);
    } catch (e) {
      Taro.hideLoading();
      Toast.error(isCancelPay(e) ? '取消购买' : '购买失败请重试');
      log('handleBuy error', e);
    }
  }, [jobId, price, productSpecId]);

  useEffect(() => {
    if (!cityCode) {
      return;
    }
    try {
      const initCity = cityValues.find(o => o.cityCode === cityCode);

      setLoading(false);
      if (initCity) {
        setCity(initCity);
      } else {
        Toast.info('当前城市不支持代发');
      }
    } catch (e) {
      Toast.error('加载失败请重试');
    }
  }, [cityCode]);

  if (loading) {
    return <PageLoading />;
  }

  return (
    <div className={PREFIX}>
      {/*<Image mode="widthFix" className={`${PREFIX}__header-image`} src="https://neighbourhood.cn/pubJob.png" />*/}
      <div className={`${PREFIX}__title`}>服务说明</div>
      <div className={`${PREFIX}__illustrate`}>
        服务方式：帮您把招聘需求<div className="underline">发到本地主播群，投递量大幅增加</div>
      </div>
      <div className={`${PREFIX}__title`}>当前通告城市</div>
      <Cell align="center" className={`${PREFIX}__cell`} title={city ? city.cityName : '暂不支持代发'} />
      {city && (
        <Fragment>
          <div className={`${PREFIX}__extra`} onClick={handleClickViewGroup}>
            查看该城市合作群列表
          </div>
          <div className={`${PREFIX}__title`}>可购买群数</div>
          <Cell align="center" className={`${PREFIX}__cell`} title={city?.count} />
          <div className={`${PREFIX}__title`}>服务费用</div>
          <div className={`${PREFIX}__cost-describe`}>
            <div className={`${PREFIX}__cost-describe__price`}>{`${price}元`}</div>
            <div className={`${PREFIX}__cost-describe__original_price`}>{`原价：${originalPrice}元`}</div>
          </div>

          <Button className={`${PREFIX}__buy-button`} onClick={handleClickBuy}>
            立即购买
          </Button>
        </Fragment>
      )}
      <SafeBottomPadding />
      <div>
        <PublishJobQrCodeDialog onClose={() => setShowQrCode(false)} open={showQrCode} />
        <Dialog open={showBuy} onClose={() => setShowBuy(false)}>
          <Dialog.Content>
            <CompanyPublishJobBuy onNext={handlePublishJob} />
          </Dialog.Content>
        </Dialog>
        <Dialog open={showPublishJob} onClose={() => setShowPublishJob(false)}>
          <Dialog.Content>
            <div className={`${PREFIX}__publish-title`}>请先发布通告</div>
            <Button className={`${PREFIX}__publish-button`} onClick={handlePublishJob}>
              发布该通告
            </Button>
          </Dialog.Content>
        </Dialog>
      </div>
    </div>
  );
}
