"use client";

import { useEffect, useState, type FormEvent } from "react";
import { useI18n } from "@/components/i18n-provider";
import type {
  MailboxMoveRuleSettings,
  MailboxSenderMoveRule,
} from "@/lib/official-mail";

type MoveRuleResponse = {
  error?: string;
  message?: string;
  ok: boolean;
  rule?: MailboxSenderMoveRule;
  settings?: MailboxMoveRuleSettings;
};

type RuleEditorState = {
  rule: MailboxSenderMoveRule | null;
  senderAddress: string;
  targetFolder: string;
};

function ClassificationIcon() {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      strokeLinejoin="round"
      className="h-5 w-5"
      aria-hidden="true"
    >
      <path d="M4 6.5h10" />
      <path d="M4 12h7" />
      <path d="M4 17.5h5" />
      <path d="m14 14 3 3 4-5" />
    </svg>
  );
}

function CloseIcon() {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      className="h-4 w-4"
      aria-hidden="true"
    >
      <path d="m7 7 10 10" />
      <path d="m17 7-10 10" />
    </svg>
  );
}

function SearchIcon() {
  return (
    <svg
      viewBox="0 0 24 24"
      fill="none"
      stroke="currentColor"
      strokeWidth="1.8"
      strokeLinecap="round"
      className="h-4 w-4"
      aria-hidden="true"
    >
      <circle cx="10.8" cy="10.8" r="6.2" />
      <path d="m15.5 15.5 4 4" />
    </svg>
  );
}

function formatRuleDate(value: string, locale: string) {
  const date = new Date(value);
  if (Number.isNaN(date.getTime())) return "-";
  return new Intl.DateTimeFormat(locale, {
    dateStyle: "medium",
    timeStyle: "short",
  }).format(date);
}

export function MailAutoClassificationPanel() {
  const { locale, tr } = useI18n();
  const [settings, setSettings] = useState<MailboxMoveRuleSettings | null>(
    null,
  );
  const [loading, setLoading] = useState(true);
  const [errorMessage, setErrorMessage] = useState("");
  const [noticeMessage, setNoticeMessage] = useState("");
  const [searchQuery, setSearchQuery] = useState("");
  const [folderFilter, setFolderFilter] = useState("all");
  const [selectedRuleIds, setSelectedRuleIds] = useState<number[]>([]);
  const [editor, setEditor] = useState<RuleEditorState | null>(null);
  const [deleteRuleIds, setDeleteRuleIds] = useState<number[]>([]);
  const [saving, setSaving] = useState(false);
  const [deleting, setDeleting] = useState(false);

  useEffect(() => {
    const controller = new AbortController();

    const loadSettings = async () => {
      try {
        const response = await fetch("/api/mailbox/move-rules", {
          cache: "no-store",
          signal: controller.signal,
        });
        if (response.status === 401) {
          window.location.assign("/login");
          return;
        }

        const payload = (await response.json()) as MoveRuleResponse;
        if (!response.ok || !payload.ok || !payload.settings) {
          throw new Error(
            payload.message ? tr(payload.message) : "load-failed",
          );
        }
        setSettings(payload.settings);
      } catch (error) {
        if (error instanceof DOMException && error.name === "AbortError")
          return;
        setErrorMessage(
          error instanceof Error && error.message !== "load-failed"
            ? error.message
            : tr(
                "자동분류 설정을 불러오지 못했습니다. 잠시 후 다시 시도해주세요.",
              ),
        );
      } finally {
        if (!controller.signal.aborted) setLoading(false);
      }
    };

    void loadSettings();
    return () => controller.abort();
  }, [tr]);

  const normalizedSearch = searchQuery.trim().toLowerCase();
  const visibleRules = (settings?.rules ?? []).filter((rule) => {
    if (folderFilter !== "all" && rule.targetFolderSystemName !== folderFilter)
      return false;
    if (!normalizedSearch) return true;
    return (
      rule.senderAddress.toLowerCase().includes(normalizedSearch) ||
      rule.targetFolderName.toLowerCase().includes(normalizedSearch)
    );
  });
  const allVisibleSelected =
    visibleRules.length > 0 &&
    visibleRules.every((rule) => selectedRuleIds.includes(rule.id));

  const openCreateEditor = () => {
    const firstFolder = settings?.folders[0];
    if (!firstFolder) {
      setErrorMessage(
        tr("자동분류를 사용하려면 내 메일함을 먼저 만들어주세요."),
      );
      return;
    }
    setErrorMessage("");
    setEditor({
      rule: null,
      senderAddress: "",
      targetFolder: firstFolder.systemName,
    });
  };

  const submitRule = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (!editor || saving) return;

    setSaving(true);
    setErrorMessage("");
    try {
      const response = await fetch("/api/mailbox/move-rules", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          ruleId: editor.rule?.id ?? null,
          senderAddress: editor.senderAddress,
          targetFolder: editor.targetFolder,
        }),
      });
      const payload = (await response.json()) as MoveRuleResponse;
      if (!response.ok || !payload.ok || !payload.rule) {
        throw new Error(payload.message ? tr(payload.message) : "save-failed");
      }

      setSettings((current) => {
        if (!current) return current;
        const nextRules = editor.rule
          ? current.rules.map((rule) =>
              rule.id === payload.rule?.id ? payload.rule : rule,
            )
          : [payload.rule as MailboxSenderMoveRule, ...current.rules];
        return { ...current, rules: nextRules };
      });
      setEditor(null);
      setNoticeMessage(
        tr(
          editor.rule
            ? "자동분류 규칙을 수정했습니다."
            : "자동분류 규칙을 추가했습니다.",
        ),
      );
    } catch (error) {
      setErrorMessage(
        error instanceof Error && error.message !== "save-failed"
          ? error.message
          : tr("자동분류 규칙을 저장하지 못했습니다."),
      );
    } finally {
      setSaving(false);
    }
  };

  const deleteRules = async () => {
    if (deleteRuleIds.length === 0 || deleting) return;

    setDeleting(true);
    setErrorMessage("");
    try {
      const response = await fetch("/api/mailbox/move-rules", {
        method: "DELETE",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ ruleIds: deleteRuleIds }),
      });
      const payload = (await response.json()) as MoveRuleResponse;
      if (!response.ok || !payload.ok) {
        throw new Error(
          payload.message ? tr(payload.message) : "delete-failed",
        );
      }

      const deletedIdSet = new Set(deleteRuleIds);
      setSettings((current) =>
        current
          ? {
              ...current,
              rules: current.rules.filter((rule) => !deletedIdSet.has(rule.id)),
            }
          : current,
      );
      setSelectedRuleIds((current) =>
        current.filter((id) => !deletedIdSet.has(id)),
      );
      setDeleteRuleIds([]);
      setNoticeMessage(tr("선택한 자동분류 규칙을 삭제했습니다."));
    } catch (error) {
      setErrorMessage(
        error instanceof Error && error.message !== "delete-failed"
          ? error.message
          : tr("자동분류 규칙을 삭제하지 못했습니다."),
      );
    } finally {
      setDeleting(false);
    }
  };

  return (
    <>
      <div className="om-setup-header lg:flex-row lg:items-start lg:justify-between lg:gap-5">
        <div className="om-setup-header-copy">
          <div className="flex items-center gap-2.5">
            <span className="inline-flex h-9 w-9 items-center justify-center rounded-[11px] bg-[#edf4ff] text-[#2f6df6]">
              <ClassificationIcon />
            </span>
            <h1 className="om-page-title text-[#16233c]">
              {tr("메일 자동분류")}
            </h1>
          </div>
          <p className="om-setup-header-description">
            {tr(
              "보낸사람별 이동 규칙을 설정하면 새로 수신되는 메일을 원하는 메일함으로 자동 정리합니다.",
            )}
          </p>
        </div>
        <button
          type="button"
          onClick={openCreateEditor}
          disabled={
            loading ||
            !settings?.folders.length ||
            (settings?.rules.length ?? 0) >= (settings?.limit ?? 1000)
          }
          className="inline-flex h-10 cursor-pointer items-center justify-center rounded-[11px] bg-[#2f6df6] px-4 text-[13px] font-semibold text-white transition-colors hover:bg-[#245de3] disabled:cursor-not-allowed disabled:bg-[#b9c7dd]"
        >
          {tr("분류 추가")}
        </button>
      </div>

      <div className="om-setup-content">
        <section className="om-setup-panel overflow-hidden bg-white">
          <div className="border-b border-[#e9eef7] px-3 py-4 sm:px-4 lg:px-5">
            <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
              <div>
                <p className="text-[14px] font-semibold text-[#243555]">
                  {tr("등록된 분류항목")}{" "}
                  <span className="text-[#2f6df6]">
                    {settings?.rules.length ?? 0}
                  </span>
                  <span className="ml-1 text-[12px] font-normal text-[#8593aa]">
                    (
                    {tr("최대 {count}개").replace(
                      "{count}",
                      String(settings?.limit ?? 1000),
                    )}
                    )
                  </span>
                </p>
                <p className="mt-1 text-[12px] text-[#74839b]">
                  {tr(
                    "분류 항목을 검색하거나 대상 메일함별로 바로 확인할 수 있습니다.",
                  )}
                </p>
              </div>
              <div className="flex min-w-0 flex-col gap-2 sm:flex-row">
                <select
                  value={folderFilter}
                  onChange={(event) => setFolderFilter(event.target.value)}
                  className="h-10 cursor-pointer rounded-[11px] border border-[#dfe7f4] bg-white px-3 text-[12px] text-[#435570] outline-none focus:border-[#b9cefa]"
                >
                  <option value="all">{tr("모든 메일함")}</option>
                  {(settings?.folders ?? []).map((folder) => (
                    <option key={folder.id} value={folder.systemName}>
                      {folder.name}
                    </option>
                  ))}
                </select>
                <label className="flex h-10 min-w-0 items-center gap-2 rounded-[11px] bg-[#f4f7fc] px-3 sm:w-[270px]">
                  <SearchIcon />
                  <input
                    value={searchQuery}
                    onChange={(event) => setSearchQuery(event.target.value)}
                    placeholder={tr("보낸사람 또는 메일함 검색")}
                    className="min-w-0 flex-1 bg-transparent text-[12px] text-[#2f405d] outline-none placeholder:text-[#9aa8bc]"
                  />
                </label>
              </div>
            </div>

            <div className="mt-3 flex items-center gap-3">
              <button
                type="button"
                disabled={selectedRuleIds.length === 0}
                onClick={() => setDeleteRuleIds(selectedRuleIds)}
                className="cursor-pointer text-[12px] font-semibold text-[#ef5268] disabled:cursor-not-allowed disabled:text-[#b7c0cf]"
              >
                {tr("선택 삭제")}
              </button>
              <span className="text-[11px] text-[#8a98ad]">
                {selectedRuleIds.length > 0
                  ? tr("{count}개 선택").replace(
                      "{count}",
                      String(selectedRuleIds.length),
                    )
                  : tr("규칙을 선택해주세요")}
              </span>
            </div>
          </div>

          {errorMessage ? (
            <div className="border-b border-[#ffe1e6] bg-[#fff7f8] px-4 py-3 text-[12px] text-[#d6465b]">
              {errorMessage}
            </div>
          ) : null}
          {noticeMessage ? (
            <div className="border-b border-[#dcebe4] bg-[#f5fbf8] px-4 py-3 text-[12px] text-[#2b7b55]">
              {noticeMessage}
            </div>
          ) : null}

          <div className="overflow-x-auto">
            <table className="w-full min-w-[720px] border-collapse text-left">
              <thead>
                <tr className="border-b border-[#edf1f7] text-[12px] font-semibold text-[#6d7d96]">
                  <th className="w-12 px-4 py-3 text-center">
                    <input
                      type="checkbox"
                      checked={allVisibleSelected}
                      onChange={(event) => {
                        const visibleIds = visibleRules.map((rule) => rule.id);
                        setSelectedRuleIds((current) =>
                          event.target.checked
                            ? [...new Set([...current, ...visibleIds])]
                            : current.filter((id) => !visibleIds.includes(id)),
                        );
                      }}
                      className="h-4 w-4 cursor-pointer rounded-[4px] accent-[#2f6df6]"
                      aria-label={tr("현재 목록 전체 선택")}
                    />
                  </th>
                  <th className="px-3 py-3">{tr("분류 기준")}</th>
                  <th className="px-3 py-3">{tr("처리 방법")}</th>
                  <th className="w-40 px-3 py-3">{tr("최근 수정")}</th>
                  <th className="w-32 px-4 py-3 text-right">{tr("관리")}</th>
                </tr>
              </thead>
              <tbody>
                {loading ? (
                  <tr>
                    <td
                      colSpan={5}
                      className="px-4 py-16 text-center text-[13px] text-[#8290a7]"
                    >
                      {tr("자동분류 설정을 불러오고 있습니다.")}
                    </td>
                  </tr>
                ) : visibleRules.length === 0 ? (
                  <tr>
                    <td
                      colSpan={5}
                      className="px-4 py-16 text-center text-[13px] text-[#8290a7]"
                    >
                      {tr(
                        normalizedSearch || folderFilter !== "all"
                          ? "검색 조건에 맞는 자동분류 규칙이 없습니다."
                          : "등록된 자동분류 규칙이 없습니다.",
                      )}
                    </td>
                  </tr>
                ) : (
                  visibleRules.map((rule) => (
                    <tr
                      key={rule.id}
                      className="border-b border-[#f0f3f8] text-[13px] text-[#33445f] transition-colors last:border-0 hover:bg-[#fafcff]"
                    >
                      <td className="px-4 py-3 text-center">
                        <input
                          type="checkbox"
                          checked={selectedRuleIds.includes(rule.id)}
                          onChange={() =>
                            setSelectedRuleIds((current) =>
                              current.includes(rule.id)
                                ? current.filter((id) => id !== rule.id)
                                : [...current, rule.id],
                            )
                          }
                          className="h-4 w-4 cursor-pointer rounded-[4px] accent-[#2f6df6]"
                          aria-label={`${rule.senderAddress} ${tr("선택")}`}
                        />
                      </td>
                      <td className="px-3 py-3">
                        <span className="text-[#72819a]">{tr("보낸사람")}</span>
                        <span className="ml-2 break-all font-semibold text-[#22324e]">
                          {rule.senderAddress}
                        </span>
                      </td>
                      <td className="px-3 py-3">
                        <span className="text-[#72819a]">
                          {tr("메일함으로 이동")}
                        </span>
                        <span className="ml-2 font-semibold text-[#2f6df6]">
                          {rule.targetFolderName}
                        </span>
                      </td>
                      <td className="px-3 py-3 text-[12px] text-[#7d8ba1]">
                        {formatRuleDate(rule.updatedAt, locale)}
                      </td>
                      <td className="px-4 py-3 text-right">
                        <button
                          type="button"
                          onClick={() =>
                            setEditor({
                              rule,
                              senderAddress: rule.senderAddress,
                              targetFolder: rule.targetFolderSystemName,
                            })
                          }
                          className="cursor-pointer text-[12px] font-semibold text-[#506581] hover:text-[#2f6df6]"
                        >
                          {tr("수정")}
                        </button>
                        <button
                          type="button"
                          onClick={() => setDeleteRuleIds([rule.id])}
                          className="ml-4 cursor-pointer text-[12px] font-semibold text-[#7f8ca0] hover:text-[#ef5268]"
                        >
                          {tr("삭제")}
                        </button>
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </section>

        <section className="rounded-[14px] bg-[#f7f9fd] px-4 py-4 text-[12px] leading-6 text-[#65758f]">
          <p className="font-semibold text-[#344966]">
            {tr("메일 자동분류 안내")}
          </p>
          <p className="mt-1">
            {tr(
              "보낸사람 주소마다 하나의 이동 규칙을 사용할 수 있습니다. 규칙을 수정하거나 삭제하기 전까지 새로 수신되는 메일에 계속 적용됩니다.",
            )}
          </p>
        </section>
      </div>

      {editor ? (
        <div
          className="fixed inset-0 z-[12200] flex items-center justify-center bg-[rgba(15,23,42,0.3)] px-4 backdrop-blur-[2px]"
          role="presentation"
          onMouseDown={(event) => {
            if (event.currentTarget === event.target && !saving)
              setEditor(null);
          }}
        >
          <form
            onSubmit={submitRule}
            className="w-full max-w-[430px] rounded-[16px] bg-white p-6 shadow-[0_28px_70px_rgba(20,31,55,0.24)]"
          >
            <div className="flex items-start justify-between gap-4">
              <div>
                <h2 className="text-[18px] font-semibold text-[#1c2940]">
                  {tr(editor.rule ? "자동분류 수정" : "자동분류 추가")}
                </h2>
                <p className="mt-1 text-[12px] text-[#7c8ba2]">
                  {tr("보낸사람 주소와 이동할 내 메일함을 선택해주세요.")}
                </p>
              </div>
              <button
                type="button"
                onClick={() => setEditor(null)}
                disabled={saving}
                className="inline-flex h-8 w-8 cursor-pointer items-center justify-center rounded-full text-[#8290a5] hover:bg-[#f4f7fb]"
              >
                <CloseIcon />
              </button>
            </div>
            <label className="mt-5 block text-[12px] font-semibold text-[#536681]">
              {tr("보낸사람 주소")}
            </label>
            <input
              type="email"
              required
              autoFocus
              value={editor.senderAddress}
              onChange={(event) =>
                setEditor((current) =>
                  current
                    ? { ...current, senderAddress: event.target.value }
                    : current,
                )
              }
              placeholder="sender@example.com"
              className="mt-2 h-11 w-full rounded-[11px] border border-[#dce5f3] px-3 text-[13px] text-[#263854] outline-none focus:border-[#b7cdf9]"
            />
            <label className="mt-4 block text-[12px] font-semibold text-[#536681]">
              {tr("이동할 메일함")}
            </label>
            <select
              required
              value={editor.targetFolder}
              onChange={(event) =>
                setEditor((current) =>
                  current
                    ? { ...current, targetFolder: event.target.value }
                    : current,
                )
              }
              className="mt-2 h-11 w-full cursor-pointer rounded-[11px] border border-[#dce5f3] bg-white px-3 text-[13px] text-[#263854] outline-none focus:border-[#b7cdf9]"
            >
              {(settings?.folders ?? []).map((folder) => (
                <option key={folder.id} value={folder.systemName}>
                  {folder.name}
                </option>
              ))}
            </select>
            <div className="mt-6 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => setEditor(null)}
                disabled={saving}
                className="h-9 cursor-pointer rounded-[9px] border border-[#dfe6f1] px-4 text-[13px] font-semibold text-[#5a6980] hover:bg-[#f7f9fc]"
              >
                {tr("취소")}
              </button>
              <button
                type="submit"
                disabled={saving}
                className="h-9 cursor-pointer rounded-[9px] bg-[#2f6df6] px-4 text-[13px] font-semibold text-white hover:bg-[#245de3] disabled:cursor-wait disabled:bg-[#9eb9f5]"
              >
                {tr(saving ? "저장 중..." : "저장")}
              </button>
            </div>
          </form>
        </div>
      ) : null}

      {deleteRuleIds.length > 0 ? (
        <div
          className="fixed inset-0 z-[12200] flex items-center justify-center bg-[rgba(15,23,42,0.3)] px-4 backdrop-blur-[2px]"
          role="presentation"
          onMouseDown={(event) => {
            if (event.currentTarget === event.target && !deleting)
              setDeleteRuleIds([]);
          }}
        >
          <section
            role="dialog"
            aria-modal="true"
            className="w-full max-w-[400px] rounded-[16px] bg-white p-6 shadow-[0_28px_70px_rgba(20,31,55,0.24)]"
          >
            <h2 className="text-[18px] font-semibold text-[#1c2940]">
              {tr("자동분류 삭제")}
            </h2>
            <p className="mt-4 text-[14px] leading-6 text-[#52627b]">
              {tr(
                deleteRuleIds.length > 1
                  ? "선택한 자동분류 규칙을 모두 삭제하시겠습니까? 이후 수신되는 메일부터 자동 이동되지 않습니다."
                  : "이 자동분류 규칙을 삭제하시겠습니까? 이후 수신되는 메일부터 자동 이동되지 않습니다.",
              )}
            </p>
            <div className="mt-6 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => setDeleteRuleIds([])}
                disabled={deleting}
                className="h-9 cursor-pointer rounded-[9px] border border-[#dfe6f1] px-4 text-[13px] font-semibold text-[#5a6980] hover:bg-[#f7f9fc]"
              >
                {tr("취소")}
              </button>
              <button
                type="button"
                onClick={() => void deleteRules()}
                disabled={deleting}
                className="h-9 cursor-pointer rounded-[9px] bg-[#ef5268] px-4 text-[13px] font-semibold text-white hover:bg-[#dc4058] disabled:cursor-wait disabled:bg-[#f3a3ae]"
              >
                {tr(deleting ? "삭제 중..." : "삭제")}
              </button>
            </div>
          </section>
        </div>
      ) : null}
    </>
  );
}
