import React, {useState} from "react";
import {Input, Popconfirm, Spin, Upload, UploadProps} from "antd";
import {CloseOutlined} from "@ant-design/icons";
import {clsx} from "clsx";

import styles from './article.module.scss'
import {getOssPolicy} from "@/service/api/common.ts";
import {showToast} from "@/components/message.ts";
import {IconAddImage, IconWarningCircle} from "@/components/icons";
import {useTranslation} from "react-i18next";

type Props = {
	children?: React.ReactNode;
	className?: string;
	data: BlockContent;
	editable?: boolean;
	onChange?: (data: BlockContent) => void;
	isFirstBlock?: boolean;
}
type ImageProps = {
	onRemove?: () => void;
	onlyUpload?: boolean;
} & Props;

const MimeTypes = ['image/jpeg', 'image/png', 'image/jpg']
const Data: { uploadConfig?: TOSSPolicy } = {}

export function BlockImage({data, editable, onChange, onlyUpload, onRemove}: ImageProps) {
	const {t} = useTranslation()
	const [loading, setLoading] = useState<number>(-1)
	// oss上传文件所需的数据
	const getUploadData: UploadProps['data'] = (file) => ({
		key: file.url,
		OSSAccessKeyId: Data.uploadConfig?.access_id,
		policy: Data.uploadConfig?.policy,
		Signature: Data.uploadConfig?.signature,
	});
	const beforeUpload = async (file: any) => {
		try {
			// 因为有超时问题，所以每次上传都重新获取参数
			Data.uploadConfig = await getOssPolicy();
			const suffix = file.name.slice(file.name.lastIndexOf('.'));
			const filename = Date.now().toString(16) + suffix;
			file.url = Data.uploadConfig.dir + filename;
		} catch (e) {
			// 设置错误状态
			file.status = 'error'
			throw e;
		}
	}
	// 处理图片上传后的状态
	const onUploadChange = async (info) => {
		if (info.fileList.length == 0) return;
		const file = info.fileList[0];
		console.log('onChange', file);
		if (file.status == 'done') {
			setLoading(-1)
			onChange?.({type: 'image', content: Data.uploadConfig?.host + '/' + file.url})
		} else if (file.status == 'error') {
			setLoading(-1)
			showToast(t('upload.upload_failed'), 'warning')
		} else if (file.status == 'uploading') {
			setLoading(file.percent)
		}
	}
	//
	return <div className={styles.image}>
		{editable && onlyUpload ? <div className={'relative'}>
			<Spin spinning={loading >= 0} percent={loading == 0 ? 'auto' : loading}>
				<Upload
					multiple={false} maxCount={1} data={getUploadData}
					showUploadList={false} accept={MimeTypes.join(',')}
					action={() => (Data.uploadConfig!.host)}
					beforeUpload={beforeUpload} onChange={onUploadChange}
				>
					<div className={styles.uploadImage}>
						{data.content ? <>
							<img src={data.content}/>
							<div className={styles.uploadTips}>
								{!onlyUpload && <Popconfirm
                                    rootClassName={'popconfirm-main'}
                                    placement={'right'}
                                    title={<div style={{minWidth: 150}}><span>{t('upload.delete_confirm')}</span></div>}
                                    onConfirm={onRemove}
                                    okText={t('delete')}
                                    cancelText={t('cancel')}
                                >
                                    <span className={styles.imageDelete}><CloseOutlined/></span>
                                </Popconfirm>}
							</div>
						</> : <div className={styles.imagePlaceholder}>
							<div className={'text-center'}>
								<IconAddImage className={"text-4xl inline-block"} />
								<div className={'text-sm'}>{t('upload.upload_image')}</div>
							</div>
						</div>}
					</div>
				</Upload>
			</Spin>
		</div> : <div className={styles.uploadImage}>
			<img src={data.content}/>
			<div className={styles.uploadTips}>
				{!onlyUpload && <Popconfirm
                    rootClassName={'popconfirm-main'}
                    placement={'right'}
                    arrow={false}
                    icon={<IconWarningCircle/>}
                    title={<div style={{minWidth: 150}}><span>{t('upload.delete_confirm')}</span></div>}
                    onConfirm={onRemove}
                    okText={t('delete')}
                    cancelText={t('cancel')}
                >
                    <span className={styles.imageDelete}><CloseOutlined/></span>
                </Popconfirm>}
			</div>
		</div>}
	</div>
}

export function BlockText({data, editable, onChange, isFirstBlock}: Props) {
	const {t} = useTranslation()
	return <div className='flex-1'>
		<div
			className={clsx(styles.text, isFirstBlock ? 'border-red-400 hover:border-red-500 focus-within:border-red-500' : '')}>
			{editable ? <div className="relative">
				{/*请输入文本内容*/}
				<Input.TextArea
					onChange={e => {
						onChange?.({type: 'text', content: e.target.value})
					}}
					placeholder={t('news.edit_notice_enter_article_content')} value={data.content} autoSize={{minRows: 4, maxRows: 5}}
					variant={"borderless"}/>
			</div> : <p className="p-2">{data.content}</p>}
		</div>
	</div>
}