"use client";

import { useSafeIntl } from "@kopexa/i18n";
import { EditIcon } from "@kopexa/icons";
import { Button, Card, Heading } from "@kopexa/sight";
import type { CardVariantProps } from "@kopexa/theme";
import { Editor, type JSONContent } from "@kopexa/tiptap";
import { useState } from "react";
import { messages } from "./messages";

// ============================================
// Types
// ============================================

export interface EditorCardProps {
	/** The content as TipTap JSONContent */
	value?: JSONContent;
	/** Callback when the content changes */
	onChange?: (content: JSONContent | undefined) => void;
	/** Title for the card header */
	title: string;
	/** Placeholder text for the editor */
	placeholder?: string;
	/** Text to show when there's no content in view mode */
	emptyText?: string;
	/** Make the component read-only */
	readOnly?: boolean;
	/** Card variant */
	cardVariant?: "default" | "accent";
	/** Props forwarded to the underlying `Card.Root` (e.g. `spacing`, `shadow`, `radius`). `cardVariant` still takes precedence for `variant`. */
	cardProps?: CardVariantProps;
	/** Size of the edit icon button. */
	editButtonSize?: "sm" | "md" | "lg";
}

export function EditorCard({
	value,
	onChange,
	title,
	placeholder,
	emptyText,
	readOnly = false,
	cardVariant = "accent",
	cardProps,
	editButtonSize = "sm",
}: EditorCardProps) {
	const intl = useSafeIntl();
	const [isEditing, setIsEditing] = useState(false);
	const [draftContent, setDraftContent] = useState<JSONContent | undefined>(
		value,
	);

	// i18n labels
	const t = {
		edit: intl.formatMessage(messages.edit),
		cancel: intl.formatMessage(messages.cancel),
		save: intl.formatMessage(messages.save),
		placeholder: placeholder ?? intl.formatMessage(messages.placeholder),
		empty: emptyText ?? intl.formatMessage(messages.empty),
	};

	const handleStartEdit = () => {
		setDraftContent(value);
		setIsEditing(true);
	};

	const handleSave = () => {
		onChange?.(draftContent);
		setIsEditing(false);
	};

	const handleCancel = () => {
		setDraftContent(value);
		setIsEditing(false);
	};

	return (
		<Card.Root
			{...cardProps}
			variant={cardVariant}
			className={isEditing ? "ring-2 ring-primary overflow-visible" : undefined}
		>
			<Card.Header className="flex flex-row items-center justify-between">
				<Heading level="h3" className="text-base">
					{title}
				</Heading>
				{!readOnly &&
					(isEditing ? (
						<div className="flex items-center gap-2">
							<Button variant="ghost" size="sm" onClick={handleCancel}>
								{t.cancel}
							</Button>
							<Button
								variant="solid"
								color="primary"
								size="sm"
								onClick={handleSave}
							>
								{t.save}
							</Button>
						</div>
					) : (
						<Button
							variant="ghost"
							size={editButtonSize}
							isIconOnly
							onClick={handleStartEdit}
							aria-label={t.edit}
						>
							<EditIcon className="size-4" />
						</Button>
					))}
			</Card.Header>
			<Card.Body className="p-0">
				{isEditing ? (
					<Editor
						variant="field"
						placeholder={t.placeholder}
						content={draftContent}
						onChange={setDraftContent}
					/>
				) : value ? (
					<Editor
						variant="default"
						bordered={false}
						content={value}
						editable={false}
					/>
				) : (
					<p className="text-sm text-muted-foreground leading-relaxed px-4 py-4">
						{t.empty}
					</p>
				)}
			</Card.Body>
		</Card.Root>
	);
}
