import { Spin } from 'antd'
import styles from './style.module.css'
import Image from 'next/image'
import { useContext, useEffect, useState } from 'react'
import AppContext from '@/components/hooks/createContext'

import CustomSlider from '@/components/CustomSlider'
import CustomUpload from '@/components/CustomUpload/Index'
import CustomTag from '@/components/CustomTag'
import PixelPerfect from '../PixelPerfect'
import { getControllerParams } from '@/pages/api/base'
import { useTranslation } from 'next-i18next'
import ControllerModel from '../../ControllerModel'

interface controllerType {
    key: string
    value: string
}

interface controllerSettings {
    [key: string]: any
}

interface IProps {
    types: controllerType[]
    settings: controllerSettings
    settingsChange: (settings: controllerSettings) => void
    previewImages?: string[]
    previewStatus?: string
    previewRequest: (key: string, module: string, imageUrl: string) => void
    refreshParams: () => void
}

const SIZE = 384

const ControllerPad = ({
    types,
    settings,
    settingsChange,
    previewImages,
    previewStatus,
    previewRequest,
    refreshParams,
}: IProps) => {
    const { t } = useTranslation('studio')
    const {
        taskId: [taskId],
        taskResult: [taskResult],
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    } = useContext(AppContext)!

    const [uploadingMain, setUploadingMain] = useState(false)

    const [btnAtrr, setBtnAtrr] = useState({
        text: t('sd.runPreprocessor'),
        icon: '/preview.svg',
        className: `${styles.loading}`,
        imageClassName: `${styles.loadingIcon}`,
    })

    useEffect(() => {
        if (previewStatus === 'Loading') {
            btnAtrr.text = t('sd.processing')
            btnAtrr.icon = '/loading.svg'
            btnAtrr.className = `${styles.previewBtn} ${styles.loadingBtn}`
            btnAtrr.imageClassName = `${styles.previewIcon} progressLoading`
        } else {
            btnAtrr.text = t('sd.runPreprocessor')
            btnAtrr.icon = '/preview.svg'
            btnAtrr.className = `${styles.previewBtn}`
            btnAtrr.imageClassName = `${styles.previewIcon}`
        }
        setBtnAtrr({ ...btnAtrr })
    }, [previewStatus])

    const [preprocessors, setPreprocessors] = useState<any[]>([])
    const [settingConfig, setSettingConfig] = useState<any[]>([])

    useEffect(() => {
        controllerTypeChoose(settings.id, settings.weshopkey)
    }, [settings.id, settings.weshopkey])

    const controllerTypeChoose = async (type: string, weshopkey: string) => {
        const data = await getControllerParams({ id: type })
        if (data) {
            setPreprocessors(data)
            if (
                !settings.module ||
                settings.module === 'none' ||
                !data.map((item: any) => item.module).includes(settings.module)
            ) {
                let preprocessorData = data[0]
                if (preprocessorData.module === 'none' && data.length > 1) {
                    preprocessorData = data[1]
                }
                const defaultSettings = getDefaultSetting(preprocessorData)
                Object.keys(preprocessorData).map((key) => {
                    if (key === 'model') {
                        return
                    }
                    if (
                        typeof preprocessorData[key] === 'object' &&
                        'default' in preprocessorData[key]
                    ) {
                        defaultSettings[key] = preprocessorData[key].default
                    }
                    Object.keys(preprocessorData).map((key) => {
                        if (
                            typeof preprocessorData[key] === 'object' &&
                            'default' in preprocessorData[key]
                        ) {
                            defaultSettings[key] = preprocessorData[key].default
                        }
                    })
                    const pre = {}
                    if (settings.pixel_perfect) {
                        pre['pixel_perfect'] = settings.pixel_perfect
                    }
                    if (settings.control_mode) {
                        pre['control_mode'] = settings.control_mode
                    }
                    if (settings.weight) {
                        pre['weight'] = settings.weight
                    }
                    if (settings.guidance_start) {
                        pre['guidance_start'] = settings.guidance_start
                    }
                    if (settings.guidance_end) {
                        pre['guidance_end'] = settings.guidance_end
                    }
                    settingsChange({
                        id: type,
                        weshopkey: weshopkey,
                        imageUrl: settings.imageUrl,
                        ...defaultSettings,
                        ...pre,
                    })
                })
            }
        }
    }

    const getDefaultSetting = (preprocessorData: any) => {
        const defaultSettings = {
            module: preprocessorData.module,
        }
        Object.keys(preprocessorData).map((key) => {
            if (typeof preprocessorData[key] === 'object' && 'default' in preprocessorData[key]) {
                defaultSettings[key] = preprocessorData[key].default
            }
        })
        return defaultSettings
    }

    useEffect(() => {
        let configs: any[] = [
            {
                type: 'tag',
                key: 'id',
                label: t('sd.controlType'),
                options: types,
            },
            {
                type: 'tag',
                key: 'module',
                label: t('sd.preprocessor'),
                options: preprocessors.map((item: any) => {
                    return {
                        key: item.module,
                        value: item.module,
                    }
                }),
            },
        ]

        const preprocessorData = preprocessors.find((it) => it.module === settings.module)

        if (preprocessorData) {
            if (preprocessorData['model']) {
                configs.push({ type: 'model' })
            }
            const list = Object.keys(preprocessorData)
                .map((key) => {
                    return { key: key, ...preprocessorData[key] }
                })
                .filter((item) => {
                    return item.idx
                })
            list.sort((a, b) => a.idx - b.idx)
            const finalList = list.map((item) => {
                const config = {}
                config['key'] = item.key
                config['label'] = item.name
                if (item.w) {
                    config['width'] = item.w == 3 ? 32 : item.w == 2 ? 49 : 100
                }
                if (item.choice) {
                    config['type'] = 'tag'
                    config['options'] = item.choice.map((it: string) => {
                        return {
                            key: it,
                            value: it,
                        }
                    })
                } else if (item.range) {
                    config['type'] = 'slider'
                    config['config'] = item.range
                }
                return config
            })
            configs = configs.concat(finalList)
        }
        setSettingConfig(configs)
    }, [preprocessors, settings.module])

    const handleChange = (key: string, value: number | string | boolean | null) => {
        if (key === 'module') {
            const preprocessorData = preprocessors.find((it) => it.module === value)
            const defaultSettings = getDefaultSetting(preprocessorData)
            settingsChange({
                ...defaultSettings,
                ...settings,
                [key]: value,
            })
        } else {
            settingsChange({
                ...settings,
                [key]: value,
            })
        }
    }

    return (
        <>
            <div className={`ag14 ${styles.container}`}>
                <div className={styles.imageContent}>
                    <Spin spinning={uploadingMain && !settings.imageUrl}>
                        {!taskResult?.showImage ? (
                            <div className={styles.originItem}>
                                {settings.imageUrl ? (
                                    <>
                                        <Image
                                            src={settings?.imageUrl || ''}
                                            width={SIZE}
                                            height={SIZE}
                                            alt="originImage"
                                            className={styles.originImage}
                                            unoptimized
                                        ></Image>
                                        <div
                                            className={styles.delete}
                                            onClick={() => {
                                                handleChange('imageUrl', null)
                                            }}
                                        >
                                            <Image
                                                src={'/modal-close.svg'}
                                                width={16}
                                                height={16}
                                                alt="deleteImage"
                                            ></Image>
                                        </div>
                                    </>
                                ) : (
                                    <div
                                        className={styles.originUploader}
                                        style={{ width: SIZE + 'px', height: SIZE + 'px' }}
                                    >
                                        <CustomUpload
                                            type={'controller'}
                                            uniqueKey={settings.weshopkey}
                                            taskId={taskId ?? ''}
                                            taskName={taskResult?.name ?? ''}
                                            beforeUpload={() => {
                                                console.info('before upload')
                                            }}
                                            uploadSuccess={(file) => {
                                                handleChange('imageUrl', file.image)
                                            }}
                                            setUploading={setUploadingMain}
                                        >
                                            <div className={styles.upload}>
                                                <div className={styles.uploadMessage}>
                                                    <Image
                                                        src="/gallery_export.svg"
                                                        alt="uploadButton"
                                                        width={24}
                                                        height={24}
                                                    ></Image>
                                                    <p className={styles.uploadText}>
                                                        {t('editMask.clickUpload')}
                                                    </p>
                                                    <p className={`${styles.dragText} ag14`}>
                                                        {t('editMask.dragUpload')}
                                                    </p>
                                                    <p className={`${styles.size} ag12`}>
                                                        {t('editMask.uploadLimitation')}
                                                    </p>
                                                </div>
                                            </div>
                                        </CustomUpload>
                                    </div>
                                )}
                                <span>{t('editMask.original')}</span>
                            </div>
                        ) : (
                            <div className={styles.originItem} style={{ width: SIZE + 'px' }}>
                                {settings?.imageUrl || taskResult.showImage ? (
                                    <Image
                                        key={settings?.imageUrl}
                                        src={settings?.imageUrl || taskResult.showImage}
                                        width={SIZE}
                                        height={SIZE}
                                        alt="originImage"
                                        className={styles.originImage}
                                        unoptimized
                                    ></Image>
                                ) : (
                                    <div
                                        style={{ width: `${SIZE}px`, height: `${SIZE}px` }}
                                        className={styles.originImage}
                                    ></div>
                                )}
                                {settings?.imageUrl ? (
                                    <div
                                        className={styles.delete}
                                        onClick={() => {
                                            handleChange('imageUrl', null)
                                        }}
                                    >
                                        <Image
                                            src={'/modal-close.svg'}
                                            width={16}
                                            height={16}
                                            alt="deleteImage"
                                        ></Image>
                                    </div>
                                ) : null}
                                <div>
                                    <span>{t('editMask.original')}</span>
                                    <span className={styles.or}>{t('editMask.selectionOr')}</span>
                                    <CustomUpload
                                        type={'controller'}
                                        uniqueKey={settings.weshopkey}
                                        taskId={taskId ?? ''}
                                        taskName={taskResult?.name ?? ''}
                                        beforeUpload={() => {
                                            console.info('before upload')
                                        }}
                                        uploadSuccess={(file) => {
                                            handleChange('imageUrl', file.image)
                                        }}
                                        setUploading={setUploadingMain}
                                        needDragger={false}
                                    >
                                        <div className={styles.uploadImage}>
                                            {t('editMask.uploadPic')}
                                        </div>
                                    </CustomUpload>
                                </div>
                            </div>
                        )}
                    </Spin>
                    <div className={`${styles.previewItem}`}>
                        {previewImages?.length ? (
                            <Image
                                src={`data:image/png;base64,${previewImages[0]}`}
                                alt="previewImage"
                                width={SIZE}
                                height={SIZE}
                                className={styles.previewImg}
                            ></Image>
                        ) : (
                            <div
                                className={styles.empty}
                                style={{ width: SIZE + 'px', height: SIZE + 'px' }}
                            ></div>
                        )}

                        <div className={styles.previewButton}>
                            <div
                                onClick={() => {
                                    previewRequest(
                                        settings.weshopkey,
                                        settings.module,
                                        settings.imageUrl,
                                    )
                                }}
                                className={`${styles.previewBtn} ${btnAtrr.className}`}
                            >
                                <Image
                                    src={btnAtrr.icon}
                                    alt="previewButton"
                                    width={14}
                                    height={14}
                                    className={btnAtrr.imageClassName}
                                ></Image>
                                <span>{btnAtrr.text}</span>
                            </div>
                        </div>
                        <div className={styles.previewText}>{t('sd.preprocessorPreview')}</div>
                    </div>
                </div>
                <div className={styles.modelContainer}>
                    {settingConfig.map((item, index) => (
                        <div
                            className={styles.modelItem}
                            key={index}
                            style={{ width: `${item.width ?? 100}%` }}
                        >
                            {item.key === 'pixel_perfect' ? (
                                <PixelPerfect
                                    pixelPerfectConfig={item}
                                    preprocessorResolutionConfig={settingConfig.find(
                                        (item) => item.key == 'processor_res',
                                    )}
                                    settings={settings}
                                    handleChange={handleChange}
                                ></PixelPerfect>
                            ) : item.key === 'processor_res' ? null : item.type === 'tag' ? (
                                <CustomTag
                                    options={item.options}
                                    value={[settings[item.key]]}
                                    onChange={(value) => {
                                        handleChange(item.key, value)
                                    }}
                                    label={item.label}
                                    refersh={item.key == 'xxxxx' ? refreshParams : null}
                                ></CustomTag>
                            ) : item.type === 'slider' ? (
                                <CustomSlider
                                    value={settings[item.key]}
                                    valueChange={(value) => {
                                        handleChange(item.key, value)
                                    }}
                                    label={item.label}
                                    config={item.config}
                                ></CustomSlider>
                            ) : item.type === 'model' ? (
                                <ControllerModel
                                    settings={settings}
                                    settingsChange={settingsChange}
                                ></ControllerModel>
                            ) : null}
                        </div>
                    ))}
                </div>
            </div>
        </>
    )
}

export default ControllerPad
