"use client";

import { useEffect, useEffectEvent, useState, type FormEvent, type ReactNode } from "react";
import type {
  MailboxCustomSpamRuleField,
  MailboxSpamGeneralSettings,
  MailboxSpamLanguage,
  MailboxSpamRuleAction,
  MailboxSpamRuleSettings
} from "@/lib/official-mail";

const RECOMMENDED_SETTINGS: MailboxSpamGeneralSettings = {
  autoMoveSpam: true,
  blockReportedSender: true,
  detectBounceSpoofing: false,
  detectMissingRecipient: false,
  detectSelfSpoofing: true,
  detectUnknownSender: false,
  expiredMessageAction: "delete",
  hideRemoteContent: true,
  hideSpamFolder: false,
  languageFilterLanguages: ["en"],
  languageFilterMode: "selected",
  languageFilterEnabled: false,
  processPreviousReported: true,
  reportedMessageAction: "spam",
  retentionDays: 30
};

const RECOMMENDED_KEYWORDS = ["성인", "대출", "광고", "홍보", "동의", "쇼핑"] as const;
const LANGUAGE_OPTIONS: Array<{ label: string; value: MailboxSpamLanguage }> = [
  { label: "영어", value: "en" },
  { label: "일본어", value: "ja" },
  { label: "러시아어", value: "ru" },
  { label: "중국어", value: "zh" }
];

type SpamSettingsTab = "general" | "keywords" | "senders";
type Notice = { message: string; tone: "error" | "success" };
type AddressEntry = {
  action: MailboxSpamRuleAction;
  id: number;
  key: string;
  kind: "custom" | "sender";
  label: string;
  type: "도메인" | "메일 주소";
};

function RadioChoice<T extends string>({ name, onChange, options, value }: {
  name: string;
  onChange: (value: T) => void;
  options: Array<{ label: string; value: T }>;
  value: T;
}) {
  return <div className="flex flex-wrap gap-x-6 gap-y-2">{options.map((option) => (
    <label key={option.value} className="inline-flex cursor-pointer items-center gap-2 text-[13px] text-[#263754]">
      <input checked={value === option.value} className="h-4 w-4 cursor-pointer accent-[#2f6df6]" name={name} onChange={() => onChange(option.value)} type="radio" />
      {option.label}
    </label>
  ))}</div>;
}

function SettingRow({ children, description, label }: { children: ReactNode; description?: ReactNode; label: ReactNode }) {
  return <div className="grid gap-3 border-b border-[#edf1f6] px-4 py-4 last:border-b-0 sm:grid-cols-[190px_minmax(0,1fr)] sm:gap-8 sm:px-5">
    <div className="text-[13px] font-semibold leading-5 text-[#253653]">{label}</div>
    <div className="min-w-0">{children}{description ? <div className="mt-2 text-[11px] leading-5 text-[#7a899f]">{description}</div> : null}</div>
  </div>;
}

function SettingsSection({ children, title }: { children: ReactNode; title: string }) {
  return <section className="border-b border-[#dfe7f2] last:border-b-0">
    <h2 className="bg-[#f8faff] px-4 py-2.5 text-[13px] font-semibold text-[#20314d] sm:px-5">{title}</h2>
    {children}
  </section>;
}

export function MailSpamSettingsPanel() {
  const [settings, setSettings] = useState<MailboxSpamRuleSettings | null>(null);
  const [generalDraft, setGeneralDraft] = useState<MailboxSpamGeneralSettings>(RECOMMENDED_SETTINGS);
  const [loading, setLoading] = useState(true);
  const [saving, setSaving] = useState(false);
  const [activeTab, setActiveTab] = useState<SpamSettingsTab>("general");
  const [allowAddress, setAllowAddress] = useState("");
  const [blockAddress, setBlockAddress] = useState("");
  const [keyword, setKeyword] = useState("");
  const [keywordField, setKeywordField] = useState<Extract<MailboxCustomSpamRuleField, "body" | "subject">>("subject");
  const [selectedKeywordIds, setSelectedKeywordIds] = useState<number[]>([]);
  const [notice, setNotice] = useState<Notice | null>(null);

  const loadSettings = async () => {
    setLoading(true);
    try {
      const response = await fetch("/api/mailbox/spam-rules", { cache: "no-store" });
      const payload = (await response.json().catch(() => null)) as { message?: string; ok?: boolean; settings?: MailboxSpamRuleSettings } | null;
      if (!response.ok || !payload?.ok || !payload.settings) throw new Error(payload?.message ?? "스팸 설정을 불러오지 못했습니다.");
      setSettings(payload.settings);
      setGeneralDraft(payload.settings.general);
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "스팸 설정을 불러오지 못했습니다.", tone: "error" });
    } finally {
      setLoading(false);
    }
  };

  const loadSettingsEffect = useEffectEvent(loadSettings);

  useEffect(() => {
    const timer = window.setTimeout(() => void loadSettingsEffect(), 0);
    return () => window.clearTimeout(timer);
  }, []);

  useEffect(() => {
    if (!notice) return;
    const timer = window.setTimeout(() => setNotice(null), 2800);
    return () => window.clearTimeout(timer);
  }, [notice]);

  const saveGeneralSettings = async () => {
    if (saving) return;
    setSaving(true);
    try {
      const response = await fetch("/api/mailbox/spam-rules", {
        body: JSON.stringify(generalDraft), headers: { "Content-Type": "application/json" }, method: "PUT"
      });
      const payload = (await response.json().catch(() => null)) as { message?: string; ok?: boolean; settings?: MailboxSpamRuleSettings } | null;
      if (!response.ok || !payload?.ok || !payload.settings) throw new Error(payload?.message ?? "스팸 설정을 저장하지 못했습니다.");
      setSettings(payload.settings);
      setGeneralDraft(payload.settings.general);
      setNotice({ message: "스팸 설정을 저장했습니다.", tone: "success" });
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "스팸 설정을 저장하지 못했습니다.", tone: "error" });
    } finally {
      setSaving(false);
    }
  };

  const saveCustomRule = async (input: { action: MailboxSpamRuleAction; field: MailboxCustomSpamRuleField; priority?: number; value: string }) => {
    const response = await fetch("/api/mailbox/spam-rules", {
      body: JSON.stringify({ ...input, kind: "custom" }), headers: { "Content-Type": "application/json" }, method: "POST"
    });
    const payload = (await response.json().catch(() => null)) as { message?: string; ok?: boolean; settings?: MailboxSpamRuleSettings } | null;
    if (!response.ok || !payload?.ok || !payload.settings) throw new Error(payload?.message ?? "스팸 규칙을 저장하지 못했습니다.");
    setSettings(payload.settings);
  };

  const deleteCustomRules = async (ruleIds: number[]) => {
    if (ruleIds.length === 0) return;
    const response = await fetch("/api/mailbox/spam-rules", {
      body: JSON.stringify({ kind: "custom", ruleIds }), headers: { "Content-Type": "application/json" }, method: "DELETE"
    });
    const payload = (await response.json().catch(() => null)) as { message?: string; ok?: boolean } | null;
    if (!response.ok || !payload?.ok) throw new Error(payload?.message ?? "규칙을 삭제하지 못했습니다.");
    await loadSettings();
  };

  const addKeyword = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (saving || !keyword.trim()) return;
    setSaving(true);
    try {
      await saveCustomRule({ action: "spam", field: keywordField, priority: 100, value: keyword });
      setKeyword("");
      setNotice({ message: "스팸 키워드를 추가했습니다.", tone: "success" });
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "키워드를 추가하지 못했습니다.", tone: "error" });
    } finally {
      setSaving(false);
    }
  };

  const toggleRecommendedKeyword = async (value: string) => {
    if (saving) return;
    const existing = settings?.customRules.find((rule) => rule.action === "spam" && (rule.field === "subject" || rule.field === "body") && rule.value === value);
    setSaving(true);
    try {
      if (existing) await deleteCustomRules([existing.id]);
      else await saveCustomRule({ action: "spam", field: "subject", priority: 100, value });
      setNotice({ message: existing ? "추천 키워드를 해제했습니다." : "추천 키워드를 적용했습니다.", tone: "success" });
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "추천 키워드를 변경하지 못했습니다.", tone: "error" });
    } finally {
      setSaving(false);
    }
  };

  const addAddressRule = async (event: FormEvent<HTMLFormElement>, action: MailboxSpamRuleAction, rawValue: string, clear: () => void) => {
    event.preventDefault();
    if (saving) return;
    const value = rawValue.trim().toLowerCase().replace(/^@/, "");
    const isEmail = value.includes("@");
    if (!value || (!isEmail && !value.includes("."))) {
      setNotice({ message: "올바른 메일 주소 또는 도메인을 입력해주세요.", tone: "error" });
      return;
    }
    setSaving(true);
    try {
      if (isEmail) {
        const response = await fetch("/api/mailbox/spam-rules", {
          body: JSON.stringify({ action, kind: "sender", moveExistingMessages: action === "spam", senderAddress: value }),
          headers: { "Content-Type": "application/json" }, method: "POST"
        });
        const payload = (await response.json().catch(() => null)) as { message?: string; ok?: boolean } | null;
        if (!response.ok || !payload?.ok) throw new Error(payload?.message ?? "주소를 저장하지 못했습니다.");
        await loadSettings();
      } else {
        await saveCustomRule({ action, field: "sender_domain", priority: 1_000_000, value });
      }
      clear();
      setNotice({ message: action === "allow" ? "수신 허용 목록에 추가했습니다." : "수신 차단 목록에 추가했습니다.", tone: "success" });
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "주소를 저장하지 못했습니다.", tone: "error" });
    } finally {
      setSaving(false);
    }
  };

  const deleteAddressEntry = async (entry: AddressEntry) => {
    if (saving) return;
    setSaving(true);
    try {
      const response = await fetch("/api/mailbox/spam-rules", {
        body: JSON.stringify(entry.kind === "sender" ? { kind: "sender", senderAddresses: [entry.label] } : { kind: "custom", ruleIds: [entry.id] }),
        headers: { "Content-Type": "application/json" }, method: "DELETE"
      });
      const payload = (await response.json().catch(() => null)) as { message?: string; ok?: boolean } | null;
      if (!response.ok || !payload?.ok) throw new Error(payload?.message ?? "주소를 삭제하지 못했습니다.");
      await loadSettings();
      setNotice({ message: "목록에서 삭제했습니다.", tone: "success" });
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "주소를 삭제하지 못했습니다.", tone: "error" });
    } finally {
      setSaving(false);
    }
  };

  const deleteSelectedKeywords = async () => {
    if (saving || selectedKeywordIds.length === 0) return;
    setSaving(true);
    try {
      await deleteCustomRules(selectedKeywordIds);
      setSelectedKeywordIds([]);
      setNotice({ message: "선택한 키워드를 삭제했습니다.", tone: "success" });
    } catch (error) {
      setNotice({ message: error instanceof Error ? error.message : "키워드를 삭제하지 못했습니다.", tone: "error" });
    } finally {
      setSaving(false);
    }
  };

  const keywordRules = settings?.customRules.filter((rule) => rule.field === "subject" || rule.field === "body") ?? [];
  const addressCustomRules = settings?.customRules.filter((rule) => rule.field === "sender" || rule.field === "sender_domain") ?? [];
  const addressEntries: AddressEntry[] = [
    ...(settings?.senderRules.map((rule) => ({ action: rule.action, id: rule.id, key: `sender-${rule.id}`, kind: "sender" as const, label: rule.senderAddress, type: "메일 주소" as const })) ?? []),
    ...addressCustomRules.map((rule) => ({ action: rule.action, id: rule.id, key: `custom-${rule.id}`, kind: "custom" as const, label: rule.value.replace(/^@/, ""), type: rule.field === "sender_domain" ? "도메인" as const : "메일 주소" as const }))
  ];
  const allowEntries = addressEntries.filter((entry) => entry.action === "allow");
  const blockEntries = addressEntries.filter((entry) => entry.action === "spam");

  const renderAddressList = (entries: AddressEntry[], emptyMessage: string) => <div className="mt-2 min-h-[138px] max-h-[230px] overflow-y-auto rounded-[7px] border border-[#dfe6ef] bg-white">
    {loading ? <div className="px-3 py-12 text-center text-[12px] text-[#8794a8]">불러오는 중...</div> : entries.length === 0 ? <div className="px-3 py-12 text-center text-[12px] text-[#8794a8]">{emptyMessage}</div> : <div className="divide-y divide-[#edf2f7]">{entries.map((entry) => (
      <div key={entry.key} className="flex items-center gap-2 px-3 py-2.5 hover:bg-[#f9fbff]">
        <span className="shrink-0 rounded-[5px] bg-[#f0f4fa] px-1.5 py-0.5 text-[10px] font-semibold text-[#63738d]">{entry.type}</span>
        <span className="min-w-0 flex-1 truncate text-[12px] text-[#293a56]">{entry.label}</span>
        <button type="button" disabled={saving} onClick={() => void deleteAddressEntry(entry)} className="shrink-0 cursor-pointer px-1 py-0.5 text-[11px] text-[#9b5261] disabled:opacity-50">삭제</button>
      </div>
    ))}</div>}
  </div>;

  return <div className="om-setup-content">
    <div className="om-setup-header"><div className="om-setup-header-copy"><h1 className="om-page-title text-[#16233c]">스팸 설정</h1><p className="om-setup-header-description">스팸 분류 방식과 키워드, 수신 허용·차단 목록을 관리합니다.</p></div></div>
    {notice ? <div className={`fixed top-5 right-5 z-[220] max-w-[calc(100vw-40px)] rounded-[12px] border bg-white px-4 py-3 text-[13px] shadow-[0_14px_40px_rgba(25,43,78,0.16)] ${notice.tone === "success" ? "border-[#ccebd9] text-[#23724b]" : "border-[#ffd8df] text-[#ad4257]"}`} role="status">{notice.message}</div> : null}

    <section className="om-setup-panel min-h-[640px] overflow-hidden bg-white">
      <div className="flex justify-start overflow-x-auto border-b border-[#e7edf7] px-0" role="tablist" aria-label="스팸 설정 메뉴">
        {([{ id: "general", label: "스팸 설정" }, { id: "keywords", label: "키워드 차단" }, { id: "senders", label: "수신 허용/차단" }] as Array<{ id: SpamSettingsTab; label: string }>).map((tab) => (
          <button key={tab.id} type="button" role="tab" aria-selected={activeTab === tab.id} onClick={() => setActiveTab(tab.id)} className={`relative h-12 shrink-0 cursor-pointer px-4 text-[13px] font-semibold transition-colors sm:px-5 ${activeTab === tab.id ? "text-[#2f6df6] after:absolute after:right-2 after:bottom-0 after:left-2 after:h-0.5 after:bg-[#2f6df6]" : "text-[#52627d] hover:text-[#2f6df6]"}`}>{tab.label}</button>
        ))}
      </div>

      {activeTab === "general" ? <div className="max-w-[980px]">{loading ? <div className="px-4 py-20 text-center text-[13px] text-[#8290a7]">스팸 설정을 불러오고 있습니다.</div> : <>
        <SettingsSection title="스팸 분류">
          <SettingRow label="스팸 자동 이동" description={<><strong>사용함</strong>으로 설정하면 스팸으로 판정된 메일을 자동으로 스팸메일함으로 이동합니다.</>}>
            <RadioChoice name="auto-move-spam" value={generalDraft.autoMoveSpam ? "on" : "off"} onChange={(value) => setGeneralDraft({ ...generalDraft, autoMoveSpam: value === "on" })} options={[{ label: "사용함", value: "on" }, { label: "사용 안 함", value: "off" }]} />
          </SettingRow>
        </SettingsSection>
        <SettingsSection title="스팸 분류 대상">
          <SettingRow label="자동 분류 대상 선택"><div className="space-y-3">{[
            { key: "detectSelfSpoofing" as const, label: "내 메일 주소를 사칭한 메일을 스팸으로 자동 분류" },
            { key: "detectBounceSpoofing" as const, label: "내 메일 주소를 사칭한 메일의 반송 메일을 스팸으로 분류" },
            { key: "detectMissingRecipient" as const, label: "받는사람에 내 메일 주소가 없으면 스팸으로 자동 분류" },
            { key: "detectUnknownSender" as const, label: "보낸사람 주소가 주소록에 없으면 스팸으로 자동 분류" }
          ].map((item) => <label key={item.key} className="flex cursor-pointer items-start gap-2.5 text-[13px] leading-5 text-[#263754]"><input type="checkbox" checked={generalDraft[item.key]} onChange={(event) => setGeneralDraft({ ...generalDraft, [item.key]: event.target.checked })} className="mt-0.5 h-4 w-4 cursor-pointer rounded accent-[#2f6df6]" /><span>{item.label}</span></label>)}
          <div>
            <label className="flex cursor-pointer items-start gap-2.5 text-[13px] leading-5 text-[#263754]"><input type="checkbox" checked={generalDraft.languageFilterEnabled} onChange={(event) => setGeneralDraft({ ...generalDraft, languageFilterEnabled: event.target.checked })} className="mt-0.5 h-4 w-4 cursor-pointer rounded accent-[#2f6df6]" /><span>언어별 스팸 분류 설정 사용</span></label>
            {generalDraft.languageFilterEnabled ? <div className="ml-6 mt-3 space-y-3 rounded-[8px] border border-[#e2e9f4] bg-[#fbfcff] p-3">
              <RadioChoice name="language-filter-mode" value={generalDraft.languageFilterMode} onChange={(value) => setGeneralDraft({ ...generalDraft, languageFilterMode: value })} options={[{ label: "모든 외국어 메일을 스팸으로 분류", value: "all" }, { label: "스팸으로 분류할 언어 직접 선택", value: "selected" }]} />
              {generalDraft.languageFilterMode === "selected" ? <div className="flex flex-wrap gap-x-5 gap-y-2 border-t border-[#edf1f6] pt-3">{LANGUAGE_OPTIONS.map((language) => { const checked = generalDraft.languageFilterLanguages.includes(language.value); return <label key={language.value} className="inline-flex cursor-pointer items-center gap-2 text-[12px] text-[#344661]"><input type="checkbox" checked={checked} disabled={checked && generalDraft.languageFilterLanguages.length === 1} onChange={(event) => setGeneralDraft({ ...generalDraft, languageFilterLanguages: event.target.checked ? [...new Set([...generalDraft.languageFilterLanguages, language.value])] : generalDraft.languageFilterLanguages.filter((value) => value !== language.value) })} className="h-4 w-4 cursor-pointer rounded accent-[#2f6df6] disabled:cursor-not-allowed disabled:opacity-50" />{language.label}</label>; })}</div> : null}
              <p className="text-[11px] leading-5 text-[#7a899f]">제목과 본문에서 같은 외국어가 우세하게 감지된 신규 메일을 스팸메일함으로 분류합니다.</p>
            </div> : null}
          </div>
          </div></SettingRow>
        </SettingsSection>
        <SettingsSection title="스팸 신고 메일 설정">
          <SettingRow label="스팸 신고 메일의 처리" description={generalDraft.reportedMessageAction === "delete" ? "영구 삭제하면 복구할 수 없습니다." : "신고한 메일을 스팸메일함으로 이동합니다."}><RadioChoice name="reported-action" value={generalDraft.reportedMessageAction} onChange={(value) => setGeneralDraft({ ...generalDraft, reportedMessageAction: value })} options={[{ label: "스팸메일함으로 이동", value: "spam" }, { label: "영구 삭제", value: "delete" }]} /></SettingRow>
          <SettingRow label="스팸 신고 메일 수신 차단"><RadioChoice name="block-reported" value={generalDraft.blockReportedSender ? "on" : "off"} onChange={(value) => setGeneralDraft({ ...generalDraft, blockReportedSender: value === "on" })} options={[{ label: "사용함", value: "on" }, { label: "사용 안 함", value: "off" }]} /></SettingRow>
          <SettingRow label={<><span className="block">스팸 신고 발송자의</span><span className="block">이전 메일 스팸 처리</span></>} description="사용함을 선택하면 같은 메일 주소에서 온 기존 메일도 함께 처리합니다."><RadioChoice name="previous-reported" value={generalDraft.processPreviousReported ? "on" : "off"} onChange={(value) => setGeneralDraft({ ...generalDraft, processPreviousReported: value === "on" })} options={[{ label: "사용함", value: "on" }, { label: "사용 안 함", value: "off" }]} /></SettingRow>
        </SettingsSection>
        <SettingsSection title="스팸메일함 설정">
          <SettingRow label="스팸메일함 숨기기"><RadioChoice name="hide-spam-folder" value={generalDraft.hideSpamFolder ? "hide" : "show"} onChange={(value) => setGeneralDraft({ ...generalDraft, hideSpamFolder: value === "hide" })} options={[{ label: "숨기기", value: "hide" }, { label: "표시하기", value: "show" }]} /></SettingRow>
          <SettingRow label="스팸메일 보관 기간"><select value={generalDraft.retentionDays} onChange={(event) => setGeneralDraft({ ...generalDraft, retentionDays: Number(event.target.value) })} className="h-9 cursor-pointer rounded-[7px] border border-[#d8e1ef] bg-white px-3 text-[12px] text-[#2c3d59] outline-none focus:border-[#8fb2ff]">{[7, 15, 30, 60, 90].map((days) => <option key={days} value={days}>{days}일</option>)}</select></SettingRow>
          <SettingRow label={<><span className="block">보관 기간 지난</span><span className="block">스팸메일 처리</span></>}><RadioChoice name="expired-action" value={generalDraft.expiredMessageAction} onChange={(value) => setGeneralDraft({ ...generalDraft, expiredMessageAction: value })} options={[{ label: "휴지통으로 이동", value: "trash" }, { label: "영구 삭제", value: "delete" }]} /></SettingRow>
          <SettingRow label={<><span className="block">스팸 메일 본문 내</span><span className="block">이미지/링크 처리</span></>} description="외부 이미지와 링크를 표시하면 발신자에게 열람 정보가 노출될 수 있습니다."><RadioChoice name="remote-content" value={generalDraft.hideRemoteContent ? "hide" : "show"} onChange={(value) => setGeneralDraft({ ...generalDraft, hideRemoteContent: value === "hide" })} options={[{ label: "숨기기", value: "hide" }, { label: "표시하기", value: "show" }]} /></SettingRow>
        </SettingsSection>
        <div className="flex flex-wrap items-center justify-between gap-3 px-4 py-5 sm:px-5"><button type="button" onClick={() => setGeneralDraft({ ...RECOMMENDED_SETTINGS })} className="cursor-pointer text-[12px] font-semibold text-[#5d6f8d] hover:text-[#2f6df6]">추천 설정으로 되돌리기</button><div className="flex gap-2"><button type="button" onClick={() => setGeneralDraft(settings?.general ?? RECOMMENDED_SETTINGS)} className="om-btn-secondary h-9 cursor-pointer rounded-[8px] px-4 text-[12px]">취소</button><button type="button" disabled={saving} onClick={() => void saveGeneralSettings()} className="om-btn-primary h-9 cursor-pointer rounded-[8px] px-5 text-[12px] disabled:opacity-60">{saving ? "저장 중..." : "저장"}</button></div></div>
      </>}</div> : null}

      {activeTab === "keywords" ? <div className="max-w-[980px]">
        <div className="border-b border-[#e7edf7] px-4 py-4 sm:px-5"><h2 className="text-[14px] font-semibold text-[#21314d]">스팸 키워드 선택</h2><p className="mt-1 text-[12px] text-[#7c8aa0]">추천 키워드를 선택하거나 직접 등록하여 차단합니다.</p></div>
        <div className="grid gap-3 border-b border-[#e7edf7] px-4 py-5 sm:grid-cols-[150px_minmax(0,1fr)] sm:px-5"><span className="text-[13px] font-semibold text-[#263754]">추천 키워드</span><div className="grid gap-x-6 gap-y-3 sm:grid-cols-3">{RECOMMENDED_KEYWORDS.map((item) => <label key={item} className="inline-flex cursor-pointer items-center gap-2 text-[13px] text-[#344661]"><input type="checkbox" checked={keywordRules.some((rule) => rule.action === "spam" && rule.value === item)} disabled={saving} onChange={() => void toggleRecommendedKeyword(item)} className="h-4 w-4 cursor-pointer accent-[#2f6df6]" />{item}</label>)}</div></div>
        <div className="border-b border-[#e7edf7] px-4 py-5 sm:px-5"><h2 className="text-[13px] font-semibold text-[#263754]">스팸 키워드 직접 등록</h2><form onSubmit={addKeyword} className="mt-3 flex max-w-[650px] flex-col gap-2 sm:flex-row"><select value={keywordField} onChange={(event) => setKeywordField(event.target.value as "body" | "subject")} className="h-10 cursor-pointer rounded-[7px] border border-[#d8e1ef] bg-white px-3 text-[12px] text-[#344661] sm:w-[120px]"><option value="subject">메일 제목</option><option value="body">메일 본문</option></select><input value={keyword} onChange={(event) => setKeyword(event.target.value)} maxLength={500} placeholder="차단할 키워드" className="h-10 min-w-0 flex-1 rounded-[7px] border border-[#d8e1ef] px-3 text-[12px] outline-none placeholder:text-[#9aa7ba] focus:border-[#8fb2ff]" /><button type="submit" disabled={saving || !keyword.trim()} className="om-btn-secondary h-10 shrink-0 cursor-pointer rounded-[7px] px-4 text-[12px] disabled:opacity-50">키워드 추가</button></form></div>
        <div className="flex items-center justify-between border-b border-[#edf2f7] px-4 py-3 sm:px-5"><span className="text-[12px] text-[#60738f]">등록된 스팸 키워드 {keywordRules.length}개 / 전체 1,000개</span><button type="button" disabled={selectedKeywordIds.length === 0 || saving} onClick={() => void deleteSelectedKeywords()} className="cursor-pointer text-[12px] font-semibold text-[#9b5261] disabled:cursor-default disabled:text-[#aeb8c7]">선택 삭제</button></div>
        {loading ? <div className="px-4 py-16 text-center text-[13px] text-[#8290a7]">불러오는 중...</div> : keywordRules.length === 0 ? <div className="px-4 py-16 text-center text-[13px] text-[#8290a7]">등록된 스팸 키워드가 없습니다.</div> : <div className="divide-y divide-[#edf2f7]">{keywordRules.map((rule) => <label key={rule.id} className="flex cursor-pointer items-center gap-3 px-4 py-3 hover:bg-[#f9fbff] sm:px-5"><input type="checkbox" checked={selectedKeywordIds.includes(rule.id)} onChange={(event) => setSelectedKeywordIds((current) => event.target.checked ? [...current, rule.id] : current.filter((id) => id !== rule.id))} className="h-4 w-4 accent-[#2f6df6]" /><span className="shrink-0 rounded-[5px] bg-[#edf4ff] px-2 py-0.5 text-[10px] font-semibold text-[#2f6df6]">{rule.field === "subject" ? "제목" : "본문"}</span><span className="min-w-0 flex-1 truncate text-[13px] text-[#293a56]">{rule.value}</span></label>)}</div>}
      </div> : null}

      {activeTab === "senders" ? <div className="max-w-[940px] px-4 py-5">
        <div className="flex flex-col gap-2 border-b border-[#e7edf7] pb-4 sm:flex-row sm:items-end sm:justify-between"><div><h2 className="text-[14px] font-semibold text-[#21314d]">수신 허용/차단 목록</h2><p className="mt-1 text-[12px] text-[#7c8aa0]">수신할 메일 주소와 차단할 메일 주소를 각각 관리합니다.</p></div><span className="text-[12px] text-[#60738f]">등록 {allowEntries.length + blockEntries.length} / {settings?.limit ?? 1000}</span></div>
        <div className="grid gap-3 border-b border-[#edf2f7] py-5 sm:grid-cols-[180px_minmax(0,520px)] sm:gap-6"><div><h3 className="text-[13px] font-semibold text-[#263754]">수신 허용 목록</h3><p className="mt-1 text-[11px] leading-5 text-[#7c8aa0]">메일 주소 또는 도메인을 등록하면 다른 스팸 규칙보다 우선하여 정상 수신합니다.</p></div><div><form onSubmit={(event) => void addAddressRule(event, "allow", allowAddress, () => setAllowAddress(""))} className="flex gap-2"><input required value={allowAddress} onChange={(event) => setAllowAddress(event.target.value)} placeholder="메일 주소 또는 도메인" className="h-9 min-w-0 flex-1 rounded-[7px] border border-[#d8e1ef] px-3 text-[12px] outline-none placeholder:text-[#9aa7ba] focus:border-[#8fb2ff]" /><button type="submit" disabled={saving} className="om-btn-secondary h-9 shrink-0 cursor-pointer rounded-[7px] px-4 text-[12px] disabled:opacity-60">추가</button></form>{renderAddressList(allowEntries, "등록된 수신 허용 주소가 없습니다.")}</div></div>
        <div className="grid gap-3 py-5 sm:grid-cols-[180px_minmax(0,520px)] sm:gap-6"><div><h3 className="text-[13px] font-semibold text-[#263754]">수신 차단 목록</h3><p className="mt-1 text-[11px] leading-5 text-[#7c8aa0]">등록한 메일 주소 또는 도메인에서 온 메일을 스팸메일함으로 이동합니다.</p></div><div><form onSubmit={(event) => void addAddressRule(event, "spam", blockAddress, () => setBlockAddress(""))} className="flex gap-2"><input required value={blockAddress} onChange={(event) => setBlockAddress(event.target.value)} placeholder="메일 주소 또는 도메인" className="h-9 min-w-0 flex-1 rounded-[7px] border border-[#d8e1ef] px-3 text-[12px] outline-none placeholder:text-[#9aa7ba] focus:border-[#8fb2ff]" /><button type="submit" disabled={saving} className="om-btn-secondary h-9 shrink-0 cursor-pointer rounded-[7px] px-4 text-[12px] disabled:opacity-60">추가</button></form>{renderAddressList(blockEntries, "등록된 수신 차단 주소가 없습니다.")}</div></div>
      </div> : null}
    </section>
  </div>;
}
