// frontend/components/settings/ConnectorList.tsx — 설정의 커넥터 그리드(메일·연결 탭 공유)
"use client";
import { Button } from "@/components/Button";
import { Icon } from "@/components/Icon";
import type { IconName } from "@/components/icons/paths";
import { AddAccountMenu } from "@/components/connectors/AddAccountMenu";
import { ConnectorCard } from "@/components/connectors/ConnectorCard";
import { connectorsApi } from "@/lib/connectors/api";
import { useConnectors } from "@/lib/hooks/useConnectors";
import type { ConnectorStatus } from "@/lib/types";
import type { ToastFn } from "./SettingsClient";

export function ConnectorList({
  title,
  subtitle,
  icon,
  filter,
  toast,
  showSyncAll = false,
  emptyText = "표시할 연결이 없어요.",
  addDomain,
  redirectAfter = "/settings",
}: {
  title: string;
  subtitle: string;
  icon: IconName;
  filter: (c: ConnectorStatus) => boolean;
  toast: ToastFn;
  showSyncAll?: boolean;
  emptyText?: string;
  addDomain?: string; // 설정 시 "계정 추가"(OAuth) 메뉴 노출
  redirectAfter?: string; // OAuth 콜백 후 복귀 경로
}) {
  const { data, isLoading, error, refresh } = useConnectors();
  const all = data ?? [];
  const items = all.filter(filter);
  const connected = items.filter((c) => c.on).length;

  const find = (id: string) => all.find((x) => x.id === id);

  const onSync = async (id: string) => {
    const c = find(id);
    try {
      const res = await connectorsApi.sync(id);
      await refresh();
      toast(`${c?.name ?? "소스"} · 새 항목 ${res.upserted}건`, c?.tone ?? "blue");
    } catch {
      toast("동기화에 실패했어요", "coral");
    }
  };

  const onDisconnect = async (id: string) => {
    const c = find(id);
    try {
      await connectorsApi.disconnect(id);
      await refresh();
      toast(`${c?.name ?? "소스"} 연결을 해제했어요`, "faint");
    } catch {
      toast("연결 해제에 실패했어요", "coral");
    }
  };

  const onImport = async (id: string, file: File) => {
    try {
      const res = await connectorsApi.importFile(id, file);
      await refresh();
      toast(res.detail || `${res.imported}건 가져왔어요`, "green");
    } catch {
      toast("이 소스는 파일 가져오기를 지원하지 않아요", "amber");
    }
  };

  const onSyncAll = async () => {
    try {
      const res = await connectorsApi.syncAll();
      await refresh();
      const total = res.reduce((n, r) => n + (r.upserted ?? 0), 0);
      toast(`전체 동기화 완료 · 새 항목 ${total}건`, "green");
    } catch {
      toast("전체 동기화에 실패했어요", "coral");
    }
  };

  return (
    <section className="set-sec" aria-label={title}>
      <header className="set-sechead">
        <h2>{title}</h2>
        <p>{subtitle}</p>
        <div className="sh-side">
          <span className="cn-count">
            {connected}/{items.length} 연결됨
          </span>
          {showSyncAll && items.length > 0 && (
            <Button variant="glass" icon="refresh" onClick={onSyncAll}>
              전체 동기화
            </Button>
          )}
          {addDomain && (
            <AddAccountMenu
              domain={addDomain}
              redirectAfter={redirectAfter}
              onError={(m) => toast(m, "coral")}
            />
          )}
        </div>
      </header>

      {error && (
        <div className="set-card" role="alert">
          연결 상태를 불러오지 못했어요
        </div>
      )}
      {isLoading && !data && <div className="set-card">불러오는 중…</div>}
      {!isLoading && items.length === 0 && (
        <div className="set-card set-empty">
          <Icon name={icon} />
          {emptyText}
        </div>
      )}

      {items.length > 0 && (
        <div className="cn-grid" role="region" tabIndex={0} aria-label={`${title} 목록`}>
          {items.map((c) => (
            <ConnectorCard
              key={c.id}
              connector={c}
              onSync={onSync}
              onDisconnect={onDisconnect}
              onImport={(file) => onImport(c.id, file)}
            />
          ))}
        </div>
      )}
    </section>
  );
}
