import styles from './style.module.css'
import { useContext, useState, useCallback, useEffect } from 'react'
import {
    downloadImgName,
    get2KImage,
    get2KImageStatus,
    getTaskDetail,
    saveTask,
} from '@/pages/api/base'
import { commonCopyText, handleDownloadClick } from '@/common/utils'
import AppContext from '../../../hooks/createContext'
import NImage from 'next/image'
import CustomModal from '../../../Modal'
import Button from '@/components/Button'
import { Checkbox } from 'antd'
import type { CheckboxChangeEvent } from 'antd/es/checkbox'
import PowerDefect from '@/components/Nav/components/Edit/components/PowerDefect'
import { useTranslation } from 'next-i18next'
import { starImage } from '@/pages/api/base'
import * as _ from 'underscore'
import Progress from './components/Progress'
import {
    IS_EN,
    IS_LOCAL,
    IS_SUBMIT_TASK,
    SHOW_COMPUTER_POWER,
} from '@/common/constans/international'
import ShopifySend from './components/Shopify'
import { PARAMS } from '@/components/hooks/constants'
import { DEFAULT_AGENT_TIPS, RETASK_AGENT } from '@/common/constans'
import StarToTask from '@/components/ShowCase/components/Detail/StarToTask'

interface Iprops {
    executionInfo: ExecutionInfo
    imageInfo: ImageInfo
    holdChange: (unitId: string | null) => void
    starCallback: (unitId: string, star: boolean) => void
    submittedInfo?: SubmitInfo
}

interface ExecutionInfo {
    taskId: string | null
    taskName: string | null
    executionId: string
    executeSeq: number | null
    agentVersion: string
}

interface SubmitInfo {
    isSubmitted: boolean
    submittedChange: (isSubmitted: boolean) => void
    id: string
}

interface ImageInfo {
    unitId: string
    image: string
    isStar: boolean
    index: number | null
    seed?: string
}

type upscaleStatus = 'Pending' | 'Completed' | 'Failed' | ''

type sendKey = 'mannequin' | 'model' | 'image2image' | 'shopify' | 'replicate'

const Opreate = ({ executionInfo, imageInfo, holdChange, starCallback, submittedInfo }: Iprops) => {
    const { t } = useTranslation(['studio', 'common'])
    const {
        userInfos: [userInfos],
        handleTaskResult,
        powerBalanceAmount: [, setPowerBalance],
        agentName: [agentName, setAgentName],
        inferResult: [, setInferResult],
        inferStarList: [, setInferStarList],
        taskId: [, setTaskId],
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    } = useContext(AppContext)!

    const downloadMenu = [
        {
            icon: '/ic_opreate_download.svg',
            finishIcon: '',
            key: 'download',
        },
        {
            icon: '/ic_opreate_4k.svg',
            finishIcon: '/ic_opreate_4k_finished.svg',
            key: '4K',
        },
    ]

    const sendMenu: { icon: string; key: sendKey; label: string }[] = IS_LOCAL
        ? [
              {
                  icon: '/ic_send_img2img.svg',
                  key: 'image2image',
                  label: t('common:scene.image2image.simple'),
              },
          ]
        : [
              {
                  icon: '/model.png',
                  key: 'mannequin',
                  label: t('common:scene.mannequin.simple'),
              },
              {
                  icon: '/real.png',
                  key: 'model',
                  label: t('common:scene.model.simple'),
              },
              {
                  icon: '/ic_send_img2img.svg',
                  key: 'image2image',
                  label: t('common:scene.image2image.simple'),
              },
          ]
    if (RETASK_AGENT.includes(agentName ?? '')) {
        sendMenu.push({
            icon: '/ic_send_replicate.svg',
            key: 'replicate',
            label: t('common:scene.replicate.simple'),
        })
    }
    if (IS_EN && userInfos?.isBindShopify) {
        sendMenu.push({
            key: 'shopify',
            icon: '',
            label: '',
        })
    }

    const [downloadShow, setDownloadShow] = useState(false)
    const [sendShow, setSendShow] = useState(false)
    const [sendDotShow, setSendDotShow] = useState(false)
    const [isNormalPending, setNormalPending] = useState(false)
    const [isUpscalePending, setUpscalePending] = useState(false)
    const [isModalOpen, setIsModalOpen] = useState(false)
    const [notRemind, setRemind] = useState(false)
    const [isPowerDefect, setIsPowerDefect] = useState(false)
    const [isStar, setStar] = useState<boolean>(imageInfo.isStar || false)

    useEffect(() => {
        if (localStorage.getItem(`opreate-send-click`)) {
            setSendDotShow(false)
        } else {
            setSendDotShow(true)
        }
    }, [])

    useEffect(() => {
        if (sendShow) {
            localStorage.setItem(`opreate-send-click`, 'true')
            setSendDotShow(false)
        }
    }, [sendShow])

    const [upscaleStatus, setUpscaleStatus] = useState<upscaleStatus>('')

    const [progress, setProgress] = useState(0)

    const getFileName = async () => {
        if (!imageInfo.index) {
            const data = await downloadImgName({
                taskId: executionInfo.taskId,
                executionId: executionInfo.executionId,
                id: imageInfo.unitId,
            })
            if (data) {
                return `${data.taskName}-${data.executeSeq}-${data.index ? data.index : '_'}`
            }
        }
        return `${executionInfo.taskName}-${executionInfo.executeSeq}-${
            imageInfo.index ? imageInfo.index : '_'
        }`
    }

    const handleDownload2KClick = () => {
        if (upscaleStatus === 'Pending') return
        if (
            localStorage.getItem('notRemind') === 'true' ||
            upscaleStatus === 'Completed' ||
            !SHOW_COMPUTER_POWER
        ) {
            upscale2KOk()
        } else {
            setIsModalOpen(true)
        }
    }

    const upscale2KOk = async () => {
        setUpscalePending(true)
        setDownloadShow(false)
        if (notRemind && localStorage.getItem('notRemind') != 'true') {
            localStorage.setItem('notRemind', `${notRemind}`)
        }
        setIsModalOpen(false)
        // 4k放大
        const logParam = window?.logger.getParams(
            window?.logger.EID.COMMON_CLICK,
            window?.logger.EVENT_TYPE.CLICK,
            {
                type: '4K',
                image: imageInfo.image,
                taskId: executionInfo.taskId,
                executionId: executionInfo.executionId,
            },
        )
        window?.logger.log([logParam])
        const fileName = await getFileName()
        const value = await get2KImage({ id: imageInfo.unitId, image: imageInfo.image })
        if (value?.image) {
            const image4KUrl = value?.image
            setPowerBalance(value?.powerBalanceAmount)
            if (image4KUrl) {
                const startTime = Date.now()
                setUpscaleStatus('Completed')
                const suc = await handleDownloadClick(image4KUrl, `${fileName}-4K`, t)
                const logParam1 = window?.logger.getParams('100000012', 3, {
                    taskId: executionInfo.taskId,
                    type: '4k',
                    image: image4KUrl,
                    costTime: Date.now() - startTime,
                    isSuccess: suc,
                })
                window?.logger.log([logParam1])
                if (!suc) {
                    setTimeout(() => {
                        window.open(image4KUrl, '_blank')
                    }, 2_000)
                }
            }
        } else if (value?.code === '2007') {
            setIsPowerDefect(true)
        }
        setUpscalePending(false)
    }

    useEffect(() => {
        const timerId = setTimeout(() => {
            looperStatus()
        }, 300)
        return () => {
            clearTimeout(timerId)
        }
    }, [imageInfo])

    useEffect(() => {
        if (upscaleStatus == 'Pending') {
            const intervalId = setInterval(looperStatus, 1000)
            return () => {
                clearInterval(intervalId)
            }
        }
    }, [upscaleStatus])

    const looperStatus = async () => {
        const data = await get2KImageStatus({ image: imageInfo.image })
        if (data) {
            setUpscaleStatus(data.upscaleStatus ?? '')
        }
    }

    const upscale2KCancel = () => {
        setIsModalOpen(false)
    }

    const downloadFinalImage = async () => {
        setNormalPending(true)
        setDownloadShow(false)
        const image = imageInfo.image
        // 结果图下载打点
        const logParam = window?.logger.getParams(
            window?.logger.EID.COMMON_CLICK,
            window?.logger.EVENT_TYPE.CLICK,
            {
                type: 'imageDownload',
                image,
                taskId: executionInfo.taskId,
                executionId: executionInfo.executionId,
            },
        )
        window?.logger.log([logParam])
        const startTime = Date.now()
        const fileName = await getFileName()
        const suc = await handleDownloadClick(image, fileName, t)
        const logParam1 = window?.logger.getParams('100000012', 3, {
            taskId: executionInfo.taskId,
            type: 'imageDownload',
            image: image,
            costTime: Date.now() - startTime,
            isSuccess: suc,
        })
        window?.logger.log([logParam1])
        if (!suc) {
            setTimeout(() => {
                window.open(image, '_blank')
            }, 2_000)
        }
        setNormalPending(false)
    }

    const orpeateClick = (key: string) => {
        switch (key) {
            case 'download':
                downloadFinalImage()
                break
            case '4K':
                handleDownload2KClick()
                break
        }
    }

    useEffect(() => {
        setStar(imageInfo.isStar)
    }, [imageInfo.isStar])

    const starItem = useCallback(
        _.debounce(() => {
            const starImageRequest = async (star: boolean) => {
                try {
                    await starImage({
                        id: imageInfo.unitId,
                        finalImage: imageInfo.image,
                        isStar: star,
                    })
                    starCallback(imageInfo.unitId, star)
                } catch (error) {
                    console.error(error)
                }
            }
            const targetStar = !isStar
            starImageRequest(targetStar)
            setStar(targetStar)
        }, 300),
        [isStar, imageInfo],
    )

    const onChange = (e: CheckboxChangeEvent) => {
        setRemind(e.target.checked)
    }

    useEffect(() => {
        const showProgress = isUpscalePending || isNormalPending
        let timerId: NodeJS.Timeout | null = null
        if (showProgress || progress) {
            timerId = setTimeout(() => {
                setProgress((preState) => {
                    let progress = preState
                    if (progress >= 100) {
                        progress = 0
                    } else if (!showProgress) {
                        if (progress < 50) {
                            progress = 50
                        } else {
                            progress = 100
                        }
                    } else if (progress < 20) {
                        progress = progress + 5
                    } else if (progress < 50) {
                        progress = progress + 2
                    } else if (progress < 80) {
                        progress = progress + 1
                    } else if (progress < 95) {
                        progress = progress + 0.25
                    }
                    return progress > 100 ? 100 : progress
                })
            }, 200)
        }
        return () => {
            if (timerId) {
                clearTimeout(timerId)
            }
        }
    }, [isUpscalePending, isNormalPending, progress])

    useEffect(() => {
        if (progress || isModalOpen || isPowerDefect || sendShow) {
            holdChange(imageInfo.unitId)
        } else {
            holdChange(null)
        }
    }, [progress, isModalOpen, isPowerDefect, sendShow])

    const sendTo = (key: string) => {
        switch (key) {
            case 'replicate':
                replicate()
                break
            default:
                newTask(key)
                break
        }
    }

    const replicate = async () => {
        const detail = await getTaskDetail({
            taskId: executionInfo.taskId,
            executionId: executionInfo.executionId,
        })
        let params
        if (detail.paramType === 'replicate') {
            params = {
                batchTask: detail?.batchTask,
                agentVersion: detail?.agentVersion,
                agentName: 'replicate',
                replicateFromTaskNo: detail.number,
                replicateFromExecuteSeq: detail.executionSeq,
                replicateFromImage: imageInfo.image,
                replicateFromUnitId: imageInfo.unitId,
            }
        } else {
            params = {
                batchTask: detail?.batchTask,
                agentVersion: detail?.agentVersion,
                agentName: 'replicate',
                paramType: detail.paramType,
                replicateFromTaskNo: detail.number,
                replicateFromExecuteSeq: detail.executionSeq,
                replicateFromTaskAgentName:
                    detail.agentName === 'replicate'
                        ? detail.replicateFromTaskAgentName
                        : detail.agentName,
                replicateFromImage: imageInfo.image,
                replicateFromUnitId: imageInfo.unitId,
            }
            PARAMS[params.paramType]?.forEach((item: string) => {
                params[item] = detail[item]
            })
        }
        const value = await saveTask(params)
        if (value) {
            setAgentName('replicate')
            setTaskId(null)
            setInferResult([])
            setInferStarList([])
            setTimeout(() => {
                setTaskId(value.taskId)
            }, 100)
        }
    }

    const newTask = async (agentName: string) => {
        const params = {
            batchTask: false,
            agentName,
            paramType: DEFAULT_AGENT_TIPS[agentName].paramType,
            image: imageInfo.image,
            agentVersion: executionInfo.agentVersion,
        }
        const value = await saveTask(params)
        if (value) {
            setAgentName(agentName)
            setTaskId(null)
            setInferResult([])
            setInferStarList([])
            setTimeout(() => {
                setTaskId(value.taskId)
                if (agentName === 'image2image') {
                    setTimeout(() => {
                        const image = new Image()
                        image.src = imageInfo.image
                        image.onload = () => {
                            handleTaskResult('sdWidthAndHeight', {
                                width: image.width,
                                height: image.height,
                            })
                        }},200)
                }
            }, 100)
        }
    }

    const copySeed = (seed?: string) => {
        if (!seed) {
            return
        }
        commonCopyText(seed, {}, t('common:toast.copySuccess'))
    }

    return (
        <>
            {imageInfo.seed ? (
                <div
                    className={`${styles.seed} ag12`}
                    onClick={() => {
                        copySeed(imageInfo.seed)
                    }}
                >
                    {imageInfo.seed}
                    <NImage
                        className={styles.copy}
                        width={12}
                        height={12}
                        alt="copy"
                        src="/ic_seed_copy.svg"
                    ></NImage>
                </div>
            ) : null}
            <div className={styles.opreate}>
                {IS_SUBMIT_TASK && submittedInfo ? (
                    <div className={styles.starSub}>
                        <StarToTask
                            id={submittedInfo.id}
                            isSubmitted={submittedInfo.isSubmitted}
                            setSubmitted={(submitted) => {
                                submittedInfo.submittedChange(submitted)
                            }}
                        ></StarToTask>
                    </div>
                ) : null}
                <div
                    className={styles.star}
                    onClick={() => {
                        starItem()
                    }}
                >
                    <NImage
                        height={20}
                        width={20}
                        alt="bookmark"
                        src={isStar ? '/ic-stared.svg' : '/ic-star.svg'}
                        className={styles.starIcon}
                    ></NImage>
                </div>

                {sendMenu.length ? (
                    <div
                        className={styles.send}
                        onClick={() => {
                            setDownloadShow(false)
                            setSendShow(true)
                        }}
                    >
                        <div className={`ag14 ${styles.sendEntry}`}>
                            <NImage
                                key={'send'}
                                src="/ic_opreate_send.svg"
                                alt="send"
                                width={20}
                                height={20}
                            ></NImage>
                        </div>
                        {sendDotShow ? <div className={styles.dot}></div> : null}
                    </div>
                ) : null}

                <div
                    className={`${styles.download} ${sendMenu.length ? styles.downloadLarge : ''}`}
                    onClick={() => {
                        setDownloadShow(true)
                    }}
                >
                    <div className={`ag14 ${styles.downloadEntry}`}>
                        {progress ? (
                            <div>
                                <Progress progress={progress}></Progress>
                            </div>
                        ) : upscaleStatus === 'Pending' ? (
                            <NImage
                                key={'loading'}
                                src="/loading.svg"
                                alt="loading"
                                width={20}
                                height={20}
                                className={`progressLoading`}
                            ></NImage>
                        ) : (
                            <NImage
                                key={'download'}
                                width={20}
                                height={20}
                                alt="download"
                                src={'/ic_opreate_download.svg'}
                            ></NImage>
                        )}
                    </div>
                </div>
                {sendShow ? (
                    <CustomModal
                        isModalOpen={sendShow}
                        setIsModalOpen={setSendShow}
                        title={t('studio:titleSend')}
                        width={408}
                    >
                        <div className={styles.sendContainer}>
                            {sendMenu.map((menu, index) => {
                                return menu.key === 'shopify' ? (
                                    <ShopifySend
                                        imageUrl={imageInfo.image}
                                        getFileName={getFileName}
                                    ></ShopifySend>
                                ) : (
                                    <div
                                        key={index}
                                        className={styles.sendItem}
                                        onClick={() => {
                                            sendTo(menu.key)
                                        }}
                                    >
                                        <NImage
                                            className={styles.sendIcon}
                                            width={48}
                                            height={48}
                                            src={menu.icon!}
                                            alt={menu.key}
                                        ></NImage>
                                        <div className={`ag12 ${styles.sendLabel}`}>
                                            {menu.label}
                                        </div>
                                    </div>
                                )
                            })}
                        </div>
                    </CustomModal>
                ) : null}

                {downloadShow ? (
                    <div className={styles.more}>
                        {downloadMenu.map((menuItem, key) => {
                            return (
                                <div
                                    className={`ag14 ${styles.opreateItem}`}
                                    key={key}
                                    onClick={() => {
                                        orpeateClick(menuItem.key)
                                    }}
                                >
                                    {((upscaleStatus === 'Pending' || isUpscalePending) &&
                                        menuItem.key === '4K') ||
                                    (isNormalPending && menuItem.key === 'download') ? (
                                        <NImage
                                            key={'loading'}
                                            src="/loading.svg"
                                            alt="loading"
                                            width={20}
                                            height={20}
                                            className={`${styles.loadingIcon} progressLoading`}
                                        ></NImage>
                                    ) : (
                                        <NImage
                                            key={menuItem.key}
                                            src={
                                                menuItem.key === '4K' &&
                                                upscaleStatus === 'Completed'
                                                    ? menuItem.finishIcon
                                                    : menuItem.icon
                                            }
                                            className={styles.icon}
                                            width={20}
                                            height={20}
                                            alt={menuItem.key}
                                        ></NImage>
                                    )}
                                    {
                                        t('studio:downloadButton', { returnObjects: true })[
                                            menuItem.key
                                        ]
                                    }
                                </div>
                            )
                        })}
                    </div>
                ) : null}

                <CustomModal
                    isModalOpen={isModalOpen && SHOW_COMPUTER_POWER}
                    setIsModalOpen={setIsModalOpen}
                    title={t('studio:title4K')}
                    width={408}
                >
                    <div className={`ag16 ${styles.powerMessage}`}>
                        <div className={styles.powerTips}>
                            <span>{t('studio:hint4K')}</span>
                            <NImage
                                src="/cpu-charge.svg"
                                width={20}
                                height={20}
                                alt="cpu-charge"
                                className={styles.cpuCharge}
                            ></NImage>
                            <span className={styles.primaryColor}>10</span>
                            <span>{t('studio:points')}</span>
                        </div>
                        <div className={styles.notice}>
                            <Checkbox onChange={onChange}>{t('studio:noFurther')}</Checkbox>
                        </div>

                        <div className={styles.btn}>
                            <div className={styles.btnItem}>
                                <Button
                                    onClick={upscale2KCancel}
                                    style={{
                                        backgroundColor: 'var(--FillColor3)',
                                        color: 'var(--TextColor1)',
                                        fontSize: '16px',
                                        lineHeight: '24px',
                                        fontWeight: '500',
                                    }}
                                >
                                    {t('common:cancel')}
                                </Button>
                            </div>
                            <div className={`${styles.btnItem} ${styles.ok}`}>
                                <Button
                                    onClick={upscale2KOk}
                                    style={{
                                        fontSize: '16px',
                                        lineHeight: '24px',
                                        fontWeight: '500',
                                    }}
                                >
                                    {t('common:confirm')}
                                </Button>
                            </div>
                        </div>
                    </div>
                </CustomModal>

                {isPowerDefect ? (
                    <PowerDefect
                        isModalOpen={isPowerDefect}
                        setIsModalOpen={setIsPowerDefect}
                    ></PowerDefect>
                ) : null}
            </div>
        </>
    )
}

export default Opreate
