import { Canvas, Image, Text, View } from '@tarojs/components'
import Taro, { useReady } from '@tarojs/taro'
import React, { useCallback, useRef, useState } from 'react'
import style from './index.module.scss'
import Dialog from '@/components/Dialog'
import LayoutBlock from '@/components/layoutBlock'
import Divider from '@/components/divider'
import type { TablePropsType } from '@/components/table'
import Table from '@/components/table'
import NormalButton from '@/components/normalButton'
import { alert } from '@/common/common'
import { GenBarCodeOrQrCode, GetInvitationInfo } from '@/api'
import { getCDNSource } from '@/common/constant'
import Painter from '@/components/painter'

const SystemInfo = Taro.getSystemInfoSync()
let screenK = 5
/**
   * 是否支持负数
   * @param {Boolean} minus 是否支持负数
   */
const toPx = (num: string, minus = false) => {
  let reg
  if (minus) {
    reg = /^-?[0-9]+([.]{1}[0-9]+){0,1}(rpx|px)$/g
  }
  else {
    reg = /^[0-9]+([.]{1}[0-9]+){0,1}(rpx|px)$/g
  }
  const results = reg.exec(num)
  console.log('results', results)
  if (!num || !results) {
    console.log(`The size: ${num} is illegal`)
    return 0
  }
  const unit = results[2]
  const value = parseFloat(num)

  let res = 0
  if (unit === 'rpx') {
    res = Math.round(value * screenK)
  }
  else if (unit === 'px') {
    res = value
  }
  return res
}
// 需要传进来的表头数据示例
const inviteColumns = [
  {
    key: 'invitee',
    title: '被邀请人',
    dataIndex: 'invitee',
    width: '50%',
  },
  {
    key: 'InviteResults',
    title: '邀请进度',
    dataIndex: 'InviteResults',
    width: '50%',
  },
]

// 邀请码
const InviteCode = () => {
  screenK = SystemInfo.screenWidth / 750

  const { fetchData } = GetInvitationInfo()
  const { fetchData: genCode } = GenBarCodeOrQrCode()
  const [inviteInfo, setInviteInfo] = useState<any>({})
  const [currentTable, setCurrentTable] = useState<TablePropsType>({
    columns: inviteColumns,
    dataSource: { list: [], total: 0 },
  })
  const [loading, setLoading] = useState(false)
  // 获取邀请码
  const getInviteCode = async() => {
    const res = await fetchData()
    if (res.success) {
      console.log('getInviteCode', res)
      setCurrentTable((prev: any) => ({
        ...prev,
        dataSource: {
          list: res.data.invitation_record.map((item, index: number) => ({
            key: index,
            index: index + 1,
            invitee: item.name || '--',
            InviteResults: '已邀请',
          })),
          total: res.data.invitation_record.length,
        },
      }))
      setInviteInfo(res.data)
    }
  }
  // 生成二维码
  const genQRcode = async() => {
    const res = await genCode({ content: `InviteCode:${inviteInfo.invitation_code}` })
    if (res.success) {
      return res.data.qrcode_base64
    }
    else {
      setLoading(false)
    }
  }

  const [, setForceUpdate] = useState({})
  const canvasNode = useRef<Taro.Canvas | null>(null)
  const ctx = useRef<Taro.RenderingContext | null>(null)
  const [showPopup, setShowPopup] = useState(false)

  const [targetImageUrl, setTargetImageUrl] = useState('')

  const getImageObject = (canvas: Taro.Canvas, src: string) => {
    return new Promise<Taro.Image>((resolve, reject) => {
      console.log('getImageObject param', canvas, src)
      const img = canvas.createImage()
      img.src = src
      img.onload = () => {
        console.log('image===>', img)
        resolve(img)
      }
      img.onerror = (err) => {
        console.log('image error===>', err)
        alert.error('图片加载失败')
        reject(err)
      }
    })
  }
  // canvas 生成 图片
  const saveCanvasToImage = (canvas) => {
    console.log('pixelRatio', SystemInfo.pixelRatio, canvas)
    Taro.canvasToTempFilePath({
      canvas,
      fileType: 'png',
      success: (res) => {
        console.log('tempFilePath', res.tempFilePath)
        setTargetImageUrl(res.tempFilePath)
      },
      fail: (error) => {
        console.log('error', error)
      },
      complete: () => {
        setLoading(false)
      },
    })
  }
  const getImageInfo = (filePath) => {
    Taro.getImageInfo({
      src: filePath,
      success: (infoRes) => {
        console.log('', infoRes)
      },
    })
  }
  // 初始化 canvas
  const initCanvas = async() => {
    return new Promise((resolve, reject) => {
      Taro.nextTick(() => {
        const query = Taro.createSelectorQuery()
        query.select('#canvas').node(({ node: canvas }: { node: Taro.Canvas }) => {
          console.log('canvas==>', canvas)
          const context = canvas.getContext('2d')
          console.log('ctx', context)
          canvasNode.current = canvas
          ctx.current = context
          console.log('canvas', canvas)
          setForceUpdate({})
          resolve(true)
        }).exec()
      })
    })
  }

  const doublePick = (num, minus = false) => {
    if (minus) {
      return num / 2
    }
    else {
      return num * 2
    }
  }
  const [canvasStyle, setCanvasStyle] = useState<React.CSSProperties>({})
  const painter = useRef<any>(null)
  const startPaint = async(ctx: Taro.RenderingContext, canvas: Taro.Canvas, image: Taro.Image) => {
    // 开始绘制
    const { width, height } = canvas
    console.log('startPaint param', ctx, canvas, image)
    const cCanvasCtx = ctx as any
    cCanvasCtx.clearRect(0, 0, width, height)
    cCanvasCtx.drawImage(image, 0, 0, width, height)
    cCanvasCtx.save()
    cCanvasCtx.font = `${doublePick(40)}px 微软雅黑`
    cCanvasCtx.fillStyle = '#000000'
    cCanvasCtx.fillText('蜘蛛管家', doublePick(40), doublePick(80)) // text up above canvas
    cCanvasCtx.save()
    cCanvasCtx.font = `${doublePick(26)}px 微软雅黑`
    cCanvasCtx.fillStyle = '#8f9398'
    cCanvasCtx.fillText('真挚邀请您建立合作关系', doublePick(40), doublePick(130)) // text up above canvas
    cCanvasCtx.save()
    cCanvasCtx.font = `${doublePick(24)}px 微软雅黑`
    cCanvasCtx.fillStyle = '#a6a6a6'
    cCanvasCtx.fillText('请前往邀请码页面，进行扫描邀请', doublePick(100), doublePick(630)) // text up above canvas
    cCanvasCtx.save()
    cCanvasCtx.font = `${doublePick(36)}px 微软雅黑`
    cCanvasCtx.fillStyle = '#7f7f7f'
    cCanvasCtx.fillText('邀 请 码', doublePick(72), doublePick(730)) // text up above canvas
    cCanvasCtx.save()
    cCanvasCtx.font = `${doublePick(24)}px 微软雅黑`
    cCanvasCtx.fillStyle = '#cccccc'
    cCanvasCtx.fillText('|', doublePick(258), doublePick(724)) // text up above canvas
    cCanvasCtx.save()
    cCanvasCtx.font = `${doublePick(36)}px 微软雅黑`
    cCanvasCtx.fillStyle = '#7f7f7f'
    cCanvasCtx.fillText(`${inviteInfo.invitation_code}`, doublePick(311), doublePick(730)) // text up above canvas
    cCanvasCtx.save()
    const codeUrl = await genQRcode()
    try {
      const code = await getImageObject(canvas, codeUrl)
      cCanvasCtx.drawImage(code, doublePick(110), doublePick(213), doublePick(342), doublePick(342))
    }
    catch (err) {
      console.error('合成二维邀请码失败', err)
      setLoading(false)
      throw new Error('合成二维邀请码失败')
    }

    saveCanvasToImage(canvas)
  }
  // 绘制最终的海报，图片使用两倍大小，canvas大小是图片的二分之一 就能让canvas生成出来的图片清晰了
  const drawPictorial = async() => {
    // eslint-disable-next-line no-async-promise-executor
    return new Promise(async(resolve, reject) => {
      setLoading(true)
      if (!ctx.current) {
        // 重新初始化canvas
        await initCanvas()
      }
      const canvas = canvasNode.current!
      Taro.getImageInfo({
        src: getCDNSource('/user/inviteCodePopup.png'),
        success: (res) => {
          console.log('res==>', res)
          canvas.width = res.width
          canvas.height = res.height
          setCanvasStyle({
            width: `${doublePick(canvas.width, true)}px`,
            height: `${doublePick(canvas.height, true)}px`,
          })
          getImageObject(canvas, `${res.path}`).then(async(image) => {
            try {
              // 开始绘制
              await startPaint(ctx.current!, canvas, image)
              resolve(true)
            }
            catch (err) {
              console.log(err)
              setLoading(false)
              reject(new Error('绘制失败'))
            }
          }).catch((error) => {
            setLoading(false)
            throw new Error(error)
          })
        },
      })
    })
  }
  // 加载更多
  const handleLoadMore = () => {

  }
  const handleQRcodeShare = async() => {
    try {
      // painter.current.startPaint()
      const flag = await drawPictorial()
      if (flag) {
        setShowPopup(true)
      }
    }
    catch (err) {
      throw new Error('弹出二维码失败')
    }
  }
  // 复制二维码
  const handleCopyInviteCode = () => {
    Taro.setClipboardData({
      data: inviteInfo.invitation_code,
    })
  }
  const handleChange = (value: boolean) => {
    setShowPopup(value)
  }
  useReady(() => {
    getInviteCode()
    setTimeout(() => {
      initCanvas()
    }, 200)
  })
  const onImgErr = (e) => {
    Taro.hideLoading()
    console.error('onImgErr', e.error)
    Taro.showToast({
      title: '生成分享图失败，请刷新页面重试',
    })
  }
  const onImgOK = (e) => {
    console.log('onImgOK', e.path)
    setTargetImageUrl(e.path)
    setShowPopup(true)
    Taro.hideLoading()
  }
  return <View className={style.main}>
    <View className={style.content}>
      <View className={style.background}>
        <View className={style.left}>
          <View className={style.title}>蜘蛛管家</View>
          <View className={style.description}>真挚邀请您建立合作关系</View>
        </View>
        <View className={style.right}>
          <View className={style.iconContainer}>
            <Image className={style.icon} src={getCDNSource('/user/inviteCode.png')} mode="widthFix" />
          </View>
        </View>
      </View>
      <View className={style.inviteCodeContent}>
        <LayoutBlock circle>
          <View className={style.codeBar}>
            <View className={style.inviteCodeBar}>
              <View className={style.invite}>邀请码</View>
              <Divider direction="vertical" />
              <View className={style.invite}>{inviteInfo.invitation_code}</View>
            </View>
            <View className={style.tips}>填写邀请码，即可在蜘蛛管家下单购物</View>
          </View>
        </LayoutBlock>
        <LayoutBlock circle customStyle={{ paddingTop: '10px', paddingBottom: '10px' }}>
          <View className={style.inviteListTitle}>
            <View className={style.titleIconLeft}></View>
            <Text className={style.listTitle}>成功邀请</Text>
            <View className={style.titleIconRight}></View>
          </View>
          <View className={style.inviteList}>
            <Table columns={currentTable.columns} emptyText="暂无邀请信息" safeAreaInsetBottom={false} dataSource={currentTable.dataSource} onLoadMore={handleLoadMore}></Table>
          </View>
        </LayoutBlock>
        <View className={style.tips} style={{ justifyContent: 'flex-start' }}>温馨提示：邀请码确定绑定后，不支持解绑。</View>
      </View>
    </View>
    {/* <Painter ref={painter} onImgErr={onImgErr} onImgOK={onImgOK} palette={imgDraw} customStyle={{ position: 'absolute', left: '-9999rpx' }}></Painter> */}
    {/* 已踩坑，这里必须设置canvas的style的width和height，单单只设置canvas实例的width和height是不行的。会模糊！ */}
    <Canvas style={{ position: 'absolute', left: '-9999rpx', ...canvasStyle }} id="canvas" type="2d" />
    <View className={style.bottomBar}>
      <NormalButton loading={loading} plain type="primary" customTextClassName={style.bottomBar__text} customStyles={{ width: '45%' }} round onClick={handleQRcodeShare}>
          二维码分享
      </NormalButton>
      <NormalButton type="primary" round customTextClassName={style.bottomBar__text} customStyles={{ width: '45%' }} onClick={handleCopyInviteCode}>
          复制邀请码
      </NormalButton>
    </View>
    <Dialog show={showPopup} onChange={handleChange}>
      <View className={style.codePreview}>
        <View className={style.imageContainer}>
          {/* showMenuByLongpress 属性只对 小程序有效 */}
          <Image className={style.image} src={targetImageUrl} mode="widthFix" id="originImage" showMenuByLongpress />
        </View>
        <Text className={style.previewTips}>长按图片保存到手机</Text>
      </View>
    </Dialog>

  </View>
}
export default InviteCode
