import {BaseFormDTO, BusinessPO} from '../../entity/common/base'
import {CSSProperties, defineComponent, PropType, VNode} from 'vue'
import './style/drawer-item.less'
import {Image} from 'ant-design-vue'
import {BaseUtil} from '../../utils/base-util'
import {LogFile} from '../../entity/system-log/log-file'
import {ImageProps} from 'ant-design-vue/lib/image'
import failImage from '../../assets/images/common/fail.svg'

export type FieldType = 'text' | 'image' | 'title' | 'divider' | 'html'

export interface DrawerItemProps<T extends BusinessPO | BaseFormDTO = BusinessPO> {
	/**
	 * 字段名称
	 * 提交表单的标识符
	 */
	name: keyof T | Array<keyof T>

	/**
	 * 字段类型
	 */
	type?: FieldType

	/**
	 * 数据格式化
	 * @param value
	 */
	format?: (entity: T, name: keyof T | Array<keyof T>, value: string | number) => string

	/**
	 * 标题
	 */
	label: string

	/**
	 * 自定义渲染
	 * @param entity
	 * @param name
	 * @param value
	 */
	render?: (entity: T, name: keyof T | Array<keyof T>, value: string | number) => VNode

	/**
	 * 占几列
	 */
	span?: number

	/**
	 * 值的额外样式
	 */
	valueClass?: string

	/**
	 * 图片的样式
	 */
	imageProps?: ImageProps
}

export const DrawerItem = defineComponent({
	name: 'DrawerItem',
	props: {
		data: {
			type: Object as PropType<BusinessPO>,
			required: true
		},
		name: {
			type: [String, Array] as PropType<DrawerItemProps['name']>,
			required: true,
			default: ''
		},
		type: {
			type: String as PropType<DrawerItemProps['type']>,
			default: 'text'
		},
		format: {
			type: Function as PropType<DrawerItemProps['format']>,
			default: (entity: BusinessPO, name: keyof BusinessPO | Array<keyof BusinessPO>, value: string | number) => value
		},
		label: {
			type: String as PropType<DrawerItemProps['label']>,
			required: true
		},
		render: {
			type: Function as PropType<DrawerItemProps['render']>
		},
		span: {
			type: Number as PropType<DrawerItemProps['span']>,
			default: 1
		},
		valueClass: {
			type: String as PropType<DrawerItemProps['valueClass']>,
			default: ''
		},
		imageProps: {
			type: Object as PropType<DrawerItemProps['imageProps']>,
			default: () => ({
				width: '100px',
				height: '100px',
				fallback: failImage
			})
		}
	},
	setup: (props, {slots}) => {
		const {data, name, type, format, label, imageProps, render, span, valueClass} = props
		const prefixCls = 'dc-drawer-detail'

		const getValue = (): string | number | undefined => {
			if (Array.isArray(name)) {
				return name.map(key => data[key]).join(',')
			}
			return data[name]
		}

		// 获取css样式
		const style: CSSProperties = {'grid-column': `span ${span}`}

		// 渲染图片
		function renderImage() {
			if (Array.isArray(name)) {
				return
			}

			const value = data[name] as unknown as string | Array<LogFile>

			if (!value || value.length === 0) {
				return '暂无' + label
			}

			// 如果是字段串，那么，分割并且显示
			if (typeof value == 'string') {
				return value.split(',').map(item => {
					return <Image src={BaseUtil.getUploadPath(item)} {...imageProps} />
				})
			}

			// 数组
			if (Array.isArray(value)) {
				return value.map((item: LogFile) => {
					return <Image
						src={BaseUtil.getUploadPath(item.uploadPath ?? item.filePath ?? item.imgPath)} {...imageProps} />
				})
			} else {
				const image = value as unknown as LogFile
				return <Image
					src={BaseUtil.getUploadPath(image.uploadPath ?? image.filePath ?? image.imgPath)} {...imageProps} />
			}
		}

		return () => {
			// 如果写了渲染函数，使用渲染函数
			if (render) {
				return render(data, name, getValue() ?? '')
			}

			// 如果自己写了默认的插槽，使用插槽
			if (slots.default) {
				return (
					<div class={`${prefixCls}-text`} style={style}>
						{slots.default({data, name, value: getValue() ?? ''})}
					</div>
				)
			}

			if (type === 'text') {
				return (
					<div class={`${prefixCls}-text`} style={style}>
						<div class={`${prefixCls}-label`}>{label}:</div>
						<div
							class={`${prefixCls}-value ${valueClass}`}>{format ? format(data, name, getValue() ?? '') : getValue() ?? '暂无'}</div>
					</div>
				)
			} else if (type === 'html') {
				return (
					<div class={`${prefixCls}-text`} style={style}>
						<div class={`${prefixCls}-label`}>{label}:</div>
						<div class={`${prefixCls}-value ${valueClass}`}
						     v-html={format ? format(data, name, getValue() ?? '') : getValue() ?? '暂无'}></div>
					</div>
				)
			} else if (type === 'image') {
				const imageStyle: CSSProperties = {
					'grid-template-columns': `repeat(auto-fill, minmax(${imageProps?.width ?? '100px'}, auto))`
				}
				return (
					<div class={`${prefixCls}-images`} style={imageStyle}>
						{renderImage()}
					</div>
				)
			} else if (type === 'title') {
				return <div class={`${prefixCls}-title`}>{label}</div>
			} else if (type === 'divider') {
				return <div class={`${prefixCls}-divider`}></div>
			} else {
				return <div>{label}</div>
			}
		}
	}
})
