import { useRef, useState } from "react";
import { AppIcon, Button } from "../ui";
import { useI18n } from "../../i18n/I18nContext";
import {
  compressDataUrlForUpload,
  filesToAttachedImages,
  MAX_ATTACHED_IMAGES,
  type AttachedImage,
} from "../../lib/attachImage";

type Props = {
  images: AttachedImage[];
  onChange: (next: AttachedImage[]) => void;
  /** 最多張數，預設 10 */
  max?: number;
  disabled?: boolean;
  /** 按鈕文案 */
  label?: string;
  /**
   * 選檔後背景上傳（回傳公開 https）。
   * 有傳則立刻上傳，送出時不必再等。
   */
  upload?: (dataUrl: string) => Promise<string>;
};

export function ImageAttach({
  images,
  onChange,
  max = MAX_ATTACHED_IMAGES,
  disabled,
  label,
  upload,
}: Props) {
  const { t } = useI18n();
  const buttonLabel = label ?? t("image.attach");
  const inputRef = useRef<HTMLInputElement>(null);
  const [err, setErr] = useState("");
  /** 用 ref 避免並行上傳時 onChange 互相覆蓋 */
  const imagesRef = useRef(images);
  imagesRef.current = images;

  function patchImage(id: string, patch: Partial<AttachedImage>) {
    const next = imagesRef.current.map((img) => (img.id === id ? { ...img, ...patch } : img));
    imagesRef.current = next;
    onChange(next);
  }

  async function uploadOne(img: AttachedImage) {
    if (!upload) {
      patchImage(img.id, { uploading: false });
      return;
    }
    try {
      const payload = await compressDataUrlForUpload(img.url);
      const remote = await upload(payload);
      if (!remote?.startsWith("http")) {
        throw new Error(t("image.uploadBadUrl"));
      }
      patchImage(img.id, {
        remoteUrl: remote,
        uploading: false,
        uploadError: undefined,
      });
    } catch (e) {
      patchImage(img.id, {
        uploading: false,
        uploadError: e instanceof Error ? e.message : t("image.uploadFail"),
      });
    }
  }

  async function onPick(files: FileList | null) {
    if (!files?.length) return;
    setErr("");
    try {
      const added = await filesToAttachedImages(files, {
        max,
        existingCount: imagesRef.current.length,
      });
      // 立刻顯示縮圖（data URL）；背景上傳
      const merged = [...imagesRef.current, ...added];
      imagesRef.current = merged;
      onChange(merged);

      if (upload) {
        // 並行上傳，不阻塞選檔 UI
        void Promise.all(added.map((img) => uploadOne(img)));
      } else {
        // 無 upload：標記完成（仍可能是 data URL，送出端自行處理）
        for (const img of added) {
          patchImage(img.id, { uploading: false });
        }
      }
    } catch (e) {
      setErr(e instanceof Error ? e.message : t("image.attachFail"));
    } finally {
      if (inputRef.current) inputRef.current.value = "";
    }
  }

  function remove(id: string) {
    const next = imagesRef.current.filter((i) => i.id !== id);
    imagesRef.current = next;
    onChange(next);
  }

  async function retry(img: AttachedImage) {
    if (!upload || img.uploading) return;
    patchImage(img.id, { uploading: true, uploadError: undefined });
    await uploadOne(img);
  }

  const full = images.length >= max;
  const uploadingN = images.filter((i) => i.uploading).length;

  return (
    <div className="hb-image-attach">
      {images.length > 0 ? (
        <div className="hb-thumb-row" aria-label={t("image.attachedAria")}>
          {images.map((img) => (
            <div key={img.id} className="hb-thumb-item">
              <img
                src={img.url}
                alt={img.name || img.prompt || t("image.alt")}
                className="hb-thumb"
                title={img.name || img.prompt || ""}
                style={img.uploading ? { opacity: 0.55 } : undefined}
              />
              {img.uploading ? (
                <span className="hb-thumb-item__badge" aria-label={t("image.uploading")}>
                  …
                </span>
              ) : null}
              {img.uploadError ? (
                <button
                  type="button"
                  className="hb-thumb-item__retry"
                  title={img.uploadError}
                  disabled={disabled}
                  onClick={() => void retry(img)}
                >
                  {t("image.retry")}
                </button>
              ) : null}
              <button
                type="button"
                className="hb-thumb-item__remove"
                aria-label={t("image.remove")}
                disabled={disabled}
                onClick={() => remove(img.id)}
              >
                <AppIcon name="close" size={14} reverse />
              </button>
            </div>
          ))}
        </div>
      ) : null}
      <div className="hb-wizard-actions" style={{ margin: 0 }}>
        <input
          ref={inputRef}
          type="file"
          accept="image/*"
          multiple
          className="hb-file-input"
          disabled={disabled || full}
          onChange={(e) => void onPick(e.target.files)}
        />
        <Button
          type="button"
          variant="ghost"
          disabled={disabled || full}
          onClick={() => inputRef.current?.click()}
        >
          {full
            ? t("image.full", { max })
            : images.length
              ? t("image.more", { n: images.length, max })
              : buttonLabel}
        </Button>
      </div>
      {uploadingN > 0 ? (
        <p className="text-muted" style={{ margin: 0, fontSize: "var(--hb-text-xs)" }}>
          {t("image.uploadingN", { n: uploadingN })}
        </p>
      ) : null}
      {err ? (
        <p className="hb-form-error" role="alert" style={{ margin: 0, fontSize: "var(--hb-text-xs)" }}>
          {err}
        </p>
      ) : null}
    </div>
  );
}
