import { useEffect, useRef, useState } from "react";
import {
    ClipboardCopy,
    ClipboardPaste,
    Eye,
    EyeOff,
    RefreshCw,
    Trash2,
} from "lucide-react";
import { Button, DynText, IconButton, Panel, Tooltip } from "../../ui/primitives";
import { confirmDialog } from "../../utils/confirm";
import { toast } from "../../ui/feedback";
import type { ClipboardState } from "../../store";
import { t } from "../../i18n";
import { formatBytes, formatRelative } from "../../utils/format";
import {
    fetchClipboard,
    readClipboardText,
    uploadClipboard,
    utf8ByteLength,
} from "./clipboard";
import s from "./ClipboardPanel.module.css";

export interface ClipboardPanelProps
{
    state: ClipboardState | null;
    selfDevice: string | null;
}

// 默认隐藏内容（隐私默认）：仅展示 meta（大小 · 类型 · 来自 X · 时间），
// 用户必须点 "显示" 才能看到原文。新内容到达（SSE 推送 / 上传回声 / 切换设备）
// 自动收回隐藏态，防止上一次显示的暴露面延续到不同内容。
//
// 操作结果走 toast。
export function ClipboardPanel(props: ClipboardPanelProps)
{
    const { state, selfDevice } = props;
    const [ busy, setBusy ] = useState(false);
    const [ revealed, setRevealed ] = useState(false);

    const hasContent = !!state && state.content.length > 0;
    const isSelf = hasContent && !!selfDevice && state.sourceDevice === selfDevice;

    // updatedAt 变化即视为"新内容"——任何来源（远端 SSE、自己上传后的回声、
    // 切换 selfDevice 后从 ETag 拉回的不同内容）都会触发收回。
    const lastUpdatedRef = useRef<number>(state?.updatedAt ?? 0);
    useEffect(() =>
    {
        const cur = state?.updatedAt ?? 0;
        if (cur !== lastUpdatedRef.current)
        {
            lastUpdatedRef.current = cur;
            setRevealed(false);
        }
    }, [ state?.updatedAt ]);

    const sizeText = hasContent
        ? formatBytes(utf8ByteLength(state.content))
        : "";
    const fromText = hasContent
        ? ( isSelf
            ? t("home.clipboard.cloudFromSelf", { time: formatRelative(state.updatedAt) })
            : t("home.clipboard.cloudFrom", {
                name: state.sourceDevice || "?",
                time: formatRelative(state.updatedAt),
            }) )
        : "";

    const handleUpload = async () =>
    {
        setBusy(true);
        try
        {
            const text = await readClipboardText();
            if (!text) { toast.warn(t("home.clipboard.uploadEmpty")); return; }
            await uploadClipboard(text);
            toast.ok("已上传到云端");
        }
        catch (e)
        {
            toast.error("剪贴板上传失败", e instanceof Error ? e.message : String(e));
        }
        finally { setBusy(false); }
    };

    const handleCopy = async () =>
    {
        if (!state) { return; }
        try
        {
            await navigator.clipboard.writeText(state.content);
            toast.ok(t("home.clipboard.copyToLocalSuccess"));
        }
        catch (e)
        {
            toast.error(t("errors.clipboardWriteFailed", {
                message: e instanceof Error ? e.message : String(e),
            }));
        }
    };

    const handleRefresh = async () =>
    {
        try { await fetchClipboard(); }
        catch (e)
        {
            toast.error("刷新失败", e instanceof Error ? e.message : String(e));
        }
    };

    const handleClear = async () =>
    {
        if (!hasContent) { return; }
        if (!await confirmDialog(t("home.clipboard.clearConfirm"))) { return; }
        setBusy(true);
        try
        {
            await uploadClipboard("");
            toast.ok(t("home.clipboard.clearSuccess"));
        }
        catch (e)
        {
            toast.error("清空失败", e instanceof Error ? e.message : String(e));
        }
        finally { setBusy(false); }
    };

    const toggleReveal = () => { setRevealed((v) => !v); };

    return (
        <Panel
            padding="default"
            title={t("home.tabs.clipboard")}
            actions={
                <div style={{ display: "inline-flex", gap: 4 }}>
                    <Tooltip label={t("home.clipboard.refresh")}>
                        <IconButton
                            aria-label={t("home.clipboard.refresh")}
                            size="sm"
                            onClick={handleRefresh}
                        >
                            <RefreshCw size={14} />
                        </IconButton>
                    </Tooltip>
                    <Tooltip label={t("home.clipboard.clear")}>
                        <IconButton
                            aria-label={t("home.clipboard.clear")}
                            size="sm"
                            onClick={handleClear}
                            disabled={!hasContent || busy}
                        >
                            <Trash2 size={14} />
                        </IconButton>
                    </Tooltip>
                </div>
            }
        >
            <div className={s.root}>
                {hasContent ? (
                    <div className={s.cloud}>
                        <div className={s.metaRow}>
                            <span className={s.metaSize}>{sizeText}</span>
                            <span className={s.metaFrom}><DynText>{fromText}</DynText></span>
                        </div>

                        {revealed ? (
                            <div className={s.content} data-jz-level="paragraph">{state.content}</div>
                        ) : (
                            <div className={s.shade}>
                                <EyeOff size={16} />
                                <span>{t("home.clipboard.hidden")}</span>
                            </div>
                        )}

                        <div className={s.actions}>
                            <Button
                                variant={revealed ? "secondary" : "primary"}
                                size="sm"
                                leftIcon={revealed ? <EyeOff size={14} /> : <Eye size={14} />}
                                onClick={toggleReveal}
                            >
                                {revealed
                                    ? t("home.clipboard.hide")
                                    : t("home.clipboard.reveal")}
                            </Button>
                            <Button
                                variant="secondary"
                                size="sm"
                                leftIcon={<ClipboardCopy size={14} />}
                                onClick={handleCopy}
                            >
                                {t("home.clipboard.copyToLocal")}
                            </Button>
                        </div>
                    </div>
                ) : (
                    <div className={s.cloudEmpty}>{t("home.clipboard.cloudEmpty")}</div>
                )}

                <div className={s.divider} />

                <div className={s.uploadHint}>{t("home.clipboard.uploadHint")}</div>
                <div className={s.actions}>
                    <Button
                        variant="primary"
                        size="sm"
                        leftIcon={<ClipboardPaste size={14} />}
                        loading={busy}
                        onClick={handleUpload}
                    >
                        {busy ? t("home.clipboard.uploading") : t("home.clipboard.uploadButton")}
                    </Button>
                </div>
            </div>
        </Panel>
    );
}
