import { Switch } from '@/components/ui/switch';
import { mergeAttributes, Node } from '@tiptap/core';
import {
	NodeViewWrapper,
	ReactNodeViewRenderer,
	type ReactNodeViewProps,
} from '@tiptap/react';
import { __ } from '@wordpress/i18n';
import { FileUp } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';

type Attrs = { label: string; required: boolean; accept: string };

declare module '@tiptap/core' {
	interface Commands<ReturnType> {
		fileUpload: {
			insertFileUpload: (attrs?: {
				label?: string;
				required?: boolean;
				accept?: string;
			}) => ReturnType;
		};
	}
}

export const FileUpload = Node.create({
	name: 'fileUpload',
	group: 'block',
	atom: true,
	selectable: true,
	draggable: true,

	addAttributes() {
		return {
			label: { default: '' },
			required: { default: false },
			accept: { default: '' },
			autoFocus: { default: false, renderHTML: () => ({}) },
		};
	},

	parseHTML() {
		return [{ tag: 'div[data-type="file-upload"]' }];
	},

	renderHTML({ HTMLAttributes }) {
		return ['div', mergeAttributes(HTMLAttributes, { 'data-type': 'file-upload' })];
	},

	addNodeView() {
		return ReactNodeViewRenderer(FileUploadComponent);
	},

	addCommands() {
		return {
			insertFileUpload:
				(attrs = {}) =>
				// eslint-disable-next-line @typescript-eslint/no-explicit-any
				({ chain }: any) =>
					chain()
						.insertContent({
							type: 'fileUpload',
							attrs: {
								label: attrs.label ?? '',
								required: attrs.required ?? false,
								accept: attrs.accept ?? '',
								autoFocus: true,
							},
						})
						.run(),
		};
	},
});

function FileUploadComponent({ node, updateAttributes }: ReactNodeViewProps) {
	const { label, required, accept, autoFocus } = node.attrs as Attrs & { autoFocus: boolean };
	const [attrs, setAttrs] = useState<Attrs>({ label, required, accept });
	const labelRef = useRef<HTMLInputElement>(null);

	useEffect(() => {
		if (autoFocus) {
			labelRef.current?.focus();
			updateAttributes({ autoFocus: false });
		}
	// eslint-disable-next-line react-hooks/exhaustive-deps
	}, []);

	return (
		<NodeViewWrapper className="rounded border bg-gray-50 p-3">
			<div className="rounded-[9px] border border-gray-200 bg-white px-4 py-3.5 transition-colors focus-within:border-teal-400">
				<div className="mb-2.5 flex items-center">
					<span className="text-[10px] font-bold tracking-widest text-teal-500 uppercase">
						{__('File Upload', 'allcoach')}
					</span>
					<div className="ml-auto flex items-center gap-1.5">
						<span className="text-[11px] text-gray-400">{__('Required?', 'allcoach')}</span>
						<Switch
							size="sm"
							checked={attrs.required}
							onCheckedChange={(v) => {
								setAttrs((prev) => ({ ...prev, required: v }));
								updateAttributes({ required: v });
							}}
						/>
					</div>
				</div>

				<input
					ref={labelRef}
					value={attrs.label}
					onChange={(e) => setAttrs((prev) => ({ ...prev, label: e.target.value }))}
					onBlur={() => updateAttributes({ label: attrs.label })}
					className="w-full border-b border-dashed border-gray-200 bg-transparent pb-1 text-[14px] font-semibold text-gray-800 outline-none placeholder:font-normal placeholder:text-gray-400 focus:border-teal-400"
					placeholder={__('Question…', 'allcoach')}
				/>

				{/* Upload zone preview */}
				<div className="mt-3 flex flex-col items-center gap-2 rounded-[9px] border-2 border-dashed border-gray-200 p-5 text-center text-gray-400">
					<FileUp className="size-5" />
					<span className="text-[12px]">{__('File upload zone', 'allcoach')}</span>
				</div>

				{/* Accepted file types */}
				<div className="mt-3">
					<label className="mb-1 block text-[11px] text-gray-400">
						{__('Allowed file types', 'allcoach')}
					</label>
					<input
						value={attrs.accept}
						onChange={(e) => setAttrs((prev) => ({ ...prev, accept: e.target.value }))}
						onBlur={() => updateAttributes({ accept: attrs.accept })}
						className="w-full rounded-md border border-gray-100 bg-gray-50 px-2.5 py-1.5 text-[12px] text-gray-700 outline-none placeholder:text-gray-400 focus:border-teal-400"
						placeholder={__('.pdf, .docx, image/*', 'allcoach')}
					/>
				</div>
			</div>
		</NodeViewWrapper>
	);
}
