import { useMemo, useState, type DragEvent } from "react";
import { Check, ScanLine } from "lucide-react";
import { DeviceTypeIcon, StateDot } from "../../ui/glyphs";
import type { DeviceKind } from "../../ui/glyphs";
import { DynText } from "../../ui/primitives";
import type { DeviceInfo } from "../../store";
import { formatRelative } from "../../utils/format";
import { t } from "../../i18n";
import s from "./DeviceStrip.module.css";

export interface DeviceStripProps
{
    devices: DeviceInfo[];
    selfDeviceName: string | null;
    selectedDevice: string | null;
    onSelect: (name: string | null) => void;
    /** 拖拽文件落到设备卡上，跳过 composer 直接发送。 */
    onDropFile?: (deviceName: string, file: File) => void;
    /** 「扫码登录新设备」入口：应用内相机扫码把另一台设备接入账号。 */
    onLinkDevice?: () => void;
}

export function DeviceStrip(props: DeviceStripProps)
{
    const { devices, selfDeviceName, selectedDevice, onSelect, onDropFile, onLinkDevice } = props;
    const [ showOffline, setShowOffline ] = useState(false);

    const peers = useMemo(
        () => devices.filter((d) => d.name !== selfDeviceName),
        [ devices, selfDeviceName ],
    );
    const visible = useMemo(
        () => (showOffline ? peers : peers.filter((d) => d.online)),
        [ peers, showOffline ],
    );
    const onlineCount  = peers.filter((d) => d.online).length;
    const offlineCount = peers.length - onlineCount;

    return (
        <section>
            <div className={s.header}>
                <div>
                    <span className={s.headerTitle}>{t("home.deviceList.title")}</span>
                    <span className={s.headerCount}>
                        <DynText>{t("home.deviceList.onlineSuffix", { count: onlineCount })}</DynText>
                    </span>
                </div>
                <div className={s.headerActions}>
                    {offlineCount > 0 && (
                        <button
                            type="button"
                            className={s.headerSwitch}
                            onClick={() => setShowOffline((v) => !v)}
                        >
                            <DynText>
                                {showOffline
                                    ? t("home.deviceList.hideOffline")
                                    : t("home.deviceList.showOffline", { count: offlineCount })}
                            </DynText>
                        </button>
                    )}
                    {onLinkDevice && (
                        <button
                            type="button"
                            className={s.headerSwitch}
                            onClick={onLinkDevice}
                        >
                            <ScanLine size={13} aria-hidden />
                            {t("qr.entry.scanNewDevice")}
                        </button>
                    )}
                </div>
            </div>

            {visible.length === 0 ? (
                <div className={s.empty}>{t("home.deviceList.empty")}</div>
            ) : (
                <div className={s.strip}>
                    {visible.map((d) => (
                        <DevicePort
                            key={d.name}
                            device={d}
                            selected={selectedDevice === d.name}
                            onClick={() => onSelect(selectedDevice === d.name ? null : d.name)}
                            onDropFile={onDropFile}
                        />
                    ))}
                </div>
            )}
        </section>
    );
}

interface DevicePortProps
{
    device: DeviceInfo;
    selected: boolean;
    onClick: () => void;
    onDropFile?: (deviceName: string, file: File) => void;
}

function DevicePort(props: DevicePortProps)
{
    const { device, selected, onClick, onDropFile } = props;
    const [ dragOver, setDragOver ] = useState(false);
    const disabled = !device.online;

    const handleDragOver = (e: DragEvent<HTMLButtonElement>) =>
    {
        if (disabled || !onDropFile) { return; }
        if (!Array.from(e.dataTransfer.types).includes("Files")) { return; }
        e.preventDefault();
        e.dataTransfer.dropEffect = "copy";
        setDragOver(true);
    };

    const handleDragLeave = () => { setDragOver(false); };

    const handleDrop = (e: DragEvent<HTMLButtonElement>) =>
    {
        if (disabled || !onDropFile) { return; }
        e.preventDefault();
        setDragOver(false);
        const f = e.dataTransfer.files[0];
        if (f) { onDropFile(device.name, f); }
    };

    const cls = [
        s.port,
        selected ? s.portSelected : "",
        disabled ? s.portOffline : "",
        dragOver ? s.portDragOver : "",
    ].filter(Boolean).join(" ");

    return (
        <button
            type="button"
            className={cls}
            onClick={onClick}
            disabled={disabled}
            aria-pressed={selected}
            onDragOver={handleDragOver}
            onDragLeave={handleDragLeave}
            onDrop={handleDrop}
        >
            <div className={s.icon}>
                <DeviceTypeIcon kind={mapKind(device.type)} size={22} />
            </div>
            <div className={s.body}>
                <div className={s.name}>{device.name}</div>
                <div className={s.meta}>
                    <StateDot tone={device.online ? "online" : "offline"} />
                    <span>
                        <DynText>
                            {device.online
                                ? t("settings.online")
                                : t("settings.lastSeen", { time: formatRelative(device.lastSeen) })}
                        </DynText>
                    </span>
                </div>
            </div>
            {selected && <Check size={14} aria-hidden />}
        </button>
    );
}

// 后端目前所有 web 接入都写 type="browser"；客户端时代会扩展为 macos/windows/...
function mapKind(type: string): DeviceKind
{
    const t = type.toLowerCase();
    if (t === "shortcut") { return "shortcut"; }
    if (t.includes("mac") || t === "darwin") { return "macos"; }
    if (t.includes("win")) { return "windows"; }
    if (t.includes("linux")) { return "linux"; }
    if (t.includes("ios") || t.includes("iphone") || t.includes("ipad")) { return "ios"; }
    if (t.includes("android")) { return "android"; }
    return "unknown";
}
