"use client";

import { useRef, useState, type ClipboardEvent } from "react";
import { useRouter } from "next/navigation";
import { BottomToast, type BottomToastNotice } from "@/components/bottom-toast";
import { useI18n } from "@/components/i18n-provider";
import type { MailSignatureSettings } from "@/lib/mail-signature";

type SignatureApiResponse = {
  error?: string;
  ok?: boolean;
  signature?: MailSignatureSettings;
};

function ToolbarIcon({ type }: { type: "bold" | "italic" | "link" | "underline" }) {
  if (type === "link") {
    return (
      <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" className="h-4 w-4" aria-hidden="true">
        <path d="M9.5 14.5 14.5 9.5" />
        <path d="M7.2 16.8 5.8 18.2a3.4 3.4 0 0 1-4.8-4.8l3.1-3.1a3.4 3.4 0 0 1 4.8 0" />
        <path d="m16.8 7.2 1.4-1.4A3.4 3.4 0 0 1 23 10.6l-3.1 3.1a3.4 3.4 0 0 1-4.8 0" />
      </svg>
    );
  }

  return (
    <span
      aria-hidden="true"
      className={`font-serif text-[15px] ${type === "bold" ? "font-bold" : ""} ${type === "italic" ? "italic" : ""} ${type === "underline" ? "underline" : ""}`}
    >
      {type === "bold" ? "B" : type === "italic" ? "I" : "U"}
    </span>
  );
}

export function MailSignatureSettingsPanel({
  initialSettings,
}: {
  initialSettings: MailSignatureSettings;
}) {
  const { tr } = useI18n();
  const router = useRouter();
  const editorRef = useRef<HTMLDivElement | null>(null);
  const imageInputRef = useRef<HTMLInputElement | null>(null);
  const [settings, setSettings] = useState(initialSettings);
  const [html, setHtml] = useState(initialSettings.html);
  const [enabled, setEnabled] = useState(initialSettings.enabled);
  const [imageWidth, setImageWidth] = useState(initialSettings.imageWidth);
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [toast, setToast] = useState<BottomToastNotice | null>(null);

  const runEditorCommand = (command: "bold" | "createLink" | "italic" | "underline") => {
    editorRef.current?.focus();

    if (command === "createLink") {
      const href = window.prompt(tr("연결할 주소를 입력해주세요."), "https://");

      if (!href?.trim()) {
        return;
      }

      document.execCommand(command, false, href.trim());
    } else {
      document.execCommand(command, false);
    }

    setHtml(editorRef.current?.innerHTML ?? "");
  };

  const uploadImage = async (file: File) => {
    if (uploading) {
      return;
    }

    setUploading(true);
    setToast(null);

    try {
      const formData = new FormData();
      formData.set("file", file);
      const response = await fetch("/api/mailbox/signature/image", {
        body: formData,
        method: "POST",
      });
      const payload = (await response.json().catch(() => ({}))) as SignatureApiResponse;

      if (!response.ok || !payload.signature) {
        throw new Error(payload.error || "서명 이미지를 업로드하지 못했습니다.");
      }

      setSettings(payload.signature);
      setToast({ tone: "success", message: "서명 이미지를 추가했습니다." });
    } catch (error) {
      setToast({
        tone: "error",
        message: error instanceof Error ? error.message : "서명 이미지를 업로드하지 못했습니다.",
      });
    } finally {
      setUploading(false);
      if (imageInputRef.current) {
        imageInputRef.current.value = "";
      }
    }
  };

  const removeImage = async () => {
    if (uploading) {
      return;
    }

    setUploading(true);
    setToast(null);

    try {
      const response = await fetch("/api/mailbox/signature/image", { method: "DELETE" });
      const payload = (await response.json().catch(() => ({}))) as SignatureApiResponse;

      if (!response.ok || !payload.signature) {
        throw new Error(payload.error || "서명 이미지를 삭제하지 못했습니다.");
      }

      setSettings(payload.signature);
      setEnabled(payload.signature.enabled);
      setToast({ tone: "success", message: "서명 이미지를 삭제했습니다." });
    } catch (error) {
      setToast({
        tone: "error",
        message: error instanceof Error ? error.message : "서명 이미지를 삭제하지 못했습니다.",
      });
    } finally {
      setUploading(false);
    }
  };

  const saveSignature = async () => {
    if (saving || uploading) {
      return;
    }

    setSaving(true);
    setToast(null);

    try {
      const response = await fetch("/api/mailbox/signature", {
        body: JSON.stringify({ enabled, html, imageWidth }),
        headers: { "Content-Type": "application/json" },
        method: "PUT",
      });
      const payload = (await response.json().catch(() => ({}))) as SignatureApiResponse;

      if (!response.ok || !payload.signature) {
        throw new Error(payload.error || "서명을 저장하지 못했습니다.");
      }

      setSettings(payload.signature);
      setHtml(payload.signature.html);
      setEnabled(payload.signature.enabled);
      setImageWidth(payload.signature.imageWidth);
      setToast({ tone: "success", message: "메일 서명을 저장했습니다." });
      router.refresh();
    } catch (error) {
      setToast({
        tone: "error",
        message: error instanceof Error ? error.message : "서명을 저장하지 못했습니다.",
      });
    } finally {
      setSaving(false);
    }
  };

  const handlePaste = (event: ClipboardEvent<HTMLDivElement>) => {
    const image = Array.from(event.clipboardData.files).find((file) => file.type.startsWith("image/"));

    if (!image) {
      return;
    }

    event.preventDefault();
    void uploadImage(image);
  };

  return (
    <div className="space-y-4">
      <div className="flex flex-col gap-3 rounded-[16px] border border-[#dbe6f7] bg-[#f8fbff] px-4 py-4 sm:flex-row sm:items-center sm:justify-between">
        <div className="min-w-0">
          <p className="text-[14px] font-semibold text-[#263957]">{tr("메일 서명 자동 삽입")}</p>
          <p className="mt-1 text-[12px] leading-5 text-[#70819d]">
            {tr("새 메일과 답장, 전달을 작성할 때 본문 끝에 자동으로 추가합니다.")}
          </p>
        </div>
        <div className="flex items-center gap-2 self-start sm:self-auto">
          <span className={`text-[12px] font-semibold ${enabled ? "text-[#2f6df6]" : "text-[#8794a8]"}`}>
            {enabled ? tr("사용") : tr("미사용")}
          </span>
          <button
            type="button"
            role="switch"
            aria-checked={enabled}
            aria-label={tr("메일 서명 자동 삽입")}
            onClick={() => setEnabled((current) => !current)}
            className={`relative h-6 w-11 shrink-0 cursor-pointer rounded-full transition-colors ${enabled ? "bg-[#2f6df6]" : "bg-[#cbd5e4]"}`}
          >
            <span
              className={`absolute left-0.5 top-0.5 h-5 w-5 rounded-full bg-white shadow-[0_1px_4px_rgba(24,52,96,0.28)] transition-transform duration-200 ${enabled ? "translate-x-5" : "translate-x-0"}`}
            />
          </button>
        </div>
      </div>

      <div className="overflow-hidden rounded-[16px] border border-[#dbe5f5] bg-white">
        <div className="flex items-center gap-1 border-b border-[#edf1f6] bg-[#fbfcff] px-2 py-2">
          {(["bold", "italic", "underline", "link"] as const).map((type) => (
            <button
              key={type}
              type="button"
              title={tr(type === "bold" ? "굵게" : type === "italic" ? "기울임" : type === "underline" ? "밑줄" : "링크")}
              aria-label={tr(type === "bold" ? "굵게" : type === "italic" ? "기울임" : type === "underline" ? "밑줄" : "링크")}
              onMouseDown={(event) => event.preventDefault()}
              onClick={() => runEditorCommand(type === "link" ? "createLink" : type)}
              className="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-[8px] text-[#526784] transition-colors hover:bg-[#edf4ff] hover:text-[#2f6df6]"
            >
              <ToolbarIcon type={type} />
            </button>
          ))}
          <span className="mx-1 h-5 w-px bg-[#e3e9f3]" />
          <button
            type="button"
            onClick={() => imageInputRef.current?.click()}
            className="inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-[8px] px-2.5 text-[12px] font-semibold text-[#526784] transition-colors hover:bg-[#edf4ff] hover:text-[#2f6df6]"
          >
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round" className="h-4 w-4" aria-hidden="true">
              <rect x="3.5" y="4.5" width="17" height="15" rx="2.5" />
              <circle cx="8.5" cy="9" r="1.4" />
              <path d="m5.5 17 4.2-4.2 2.8 2.6 2.2-2.2 3.8 3.8" />
            </svg>
            {uploading ? tr("업로드 중") : tr("명함 이미지")}
          </button>
          <input
            ref={imageInputRef}
            type="file"
            accept="image/jpeg,image/png,image/gif,image/webp"
            className="hidden"
            onChange={(event) => {
              const file = event.currentTarget.files?.[0];
              if (file) void uploadImage(file);
            }}
          />
        </div>

        <div
          ref={editorRef}
          contentEditable
          suppressContentEditableWarning
          role="textbox"
          aria-label={tr("메일 서명 내용")}
          data-i18n-skip
          data-placeholder={tr("이름, 직책, 회사명, 연락처, 주소 등 고정으로 표시할 내용을 입력하세요.")}
          dangerouslySetInnerHTML={{ __html: html }}
          onInput={(event) => setHtml(event.currentTarget.innerHTML)}
          onPaste={handlePaste}
          className="mail-signature-editor min-h-[170px] px-4 py-4 text-[14px] leading-6 text-[#263957] outline-none empty:before:pointer-events-none empty:before:text-[#9aa8bc] empty:before:content-[attr(data-placeholder)]"
        />

        {settings.imageUrl ? (
          <div className="border-t border-[#edf1f6] px-4 py-4">
            <div className="flex flex-col gap-3 sm:flex-row sm:items-end sm:justify-between">
              <div className="min-w-0 overflow-hidden rounded-[12px] border border-[#e3e9f3] bg-[linear-gradient(135deg,#f8fbff,#f2f6fc)] p-3">
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={settings.imageUrl}
                  alt={tr("메일 서명 이미지 미리보기")}
                  style={{ width: `${imageWidth}px` }}
                  className="block h-auto max-w-full"
                />
              </div>
              <div className="flex shrink-0 flex-wrap items-center gap-2">
                <span className="text-[12px] font-semibold text-[#70819d]">{tr("이미지 너비")}</span>
                {[
                  { label: "작게", value: 280 },
                  { label: "보통", value: 420 },
                  { label: "크게", value: 600 },
                ].map((option) => (
                  <button
                    key={option.value}
                    type="button"
                    onClick={() => setImageWidth(option.value)}
                    className={`h-8 cursor-pointer rounded-[8px] border px-2.5 text-[12px] font-semibold transition-colors ${imageWidth === option.value ? "border-[#bcd1ff] bg-[#edf4ff] text-[#2f6df6]" : "border-[#e1e7f0] bg-white text-[#66758d] hover:border-[#cddcff] hover:text-[#2f6df6]"}`}
                  >
                    {tr(option.label)}
                  </button>
                ))}
                <button
                  type="button"
                  onClick={() => void removeImage()}
                  className="h-8 cursor-pointer rounded-[8px] px-2 text-[12px] font-semibold text-[#b54a5b] transition-colors hover:bg-[#fff4f6]"
                >
                  {tr("삭제")}
                </button>
              </div>
            </div>
          </div>
        ) : null}
      </div>

      <div className="flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between">
        <p className="text-[12px] leading-5 text-[#7b8ca8]">
          {tr("JPG, PNG, GIF, WebP 이미지를 5MB 이하로 사용할 수 있습니다.")}
        </p>
        <button
          type="button"
          disabled={saving || uploading}
          onClick={() => void saveSignature()}
          className="om-btn-primary h-10 shrink-0 cursor-pointer rounded-[10px] px-4 text-[13px] shadow-none hover:shadow-none disabled:cursor-not-allowed disabled:opacity-60"
        >
          {saving ? tr("저장 중...") : tr("서명 저장")}
        </button>
      </div>

      {toast ? <BottomToast notice={toast} onClose={() => setToast(null)} /> : null}
    </div>
  );
}
