import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
  ArrowLeft,
  Plus,
  Save,
  Shield,
  Sparkles,
  Trash2,
  Upload,
} from "lucide-react";
import { useEffect, useState } from "react";
import { Link, useNavigate, useParams } from "react-router-dom";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "../../components/ui/card";
import { Input } from "../../components/ui/input";
import { Label } from "../../components/ui/label";
import { Switch } from "../../components/ui/switch";
import { Textarea } from "../../components/ui/textarea";
import { toast } from "../../components/ui/use-toast";
import {
  createClient,
  deleteClient,
  fetchClient,
  updateClient,
  updateClientStatus,
} from "../../lib/devApi";
import type {
  ClientStatus,
  ClientType,
  ClientUpsertRequest,
} from "../../lib/devApi";
import { t } from "../../lib/i18n";
import { cn } from "../../lib/utils";
import { tryConvertToJwks } from "../../lib/keyUtils";

interface ScopeItem {
  id: string;
  name: string;
  description: string;
  mandatory: boolean;
}

type SecurityProfile = "private" | "pkce";
type TokenEndpointAuthMethod =
  | "none"
  | "client_secret_basic"
  | "private_key_jwt";

function isTokenEndpointAuthMethod(
  value: string,
): value is TokenEndpointAuthMethod {
  return (
    value === "none" ||
    value === "client_secret_basic" ||
    value === "private_key_jwt"
  );
}

function readMetadataString(
  metadata: Record<string, unknown>,
  key: string,
): string {
  const value = metadata[key];
  return typeof value === "string" ? value : "";
}

function readMetadataObject(
  metadata: Record<string, unknown>,
  key: string,
): Record<string, unknown> | undefined {
  const value = metadata[key];
  if (typeof value !== "object" || value === null || Array.isArray(value)) {
    return undefined;
  }
  return value as Record<string, unknown>;
}

function isValidUrl(value: string): boolean {
  try {
    const url = new URL(value);
    return url.protocol === "https:" || url.protocol === "http:";
  } catch {
    return false;
  }
}

function isValidJson(value: string): boolean {
  if (!value.trim()) return false;
  try {
    JSON.parse(value);
    return true;
  } catch {
    return false;
  }
}

function ClientGeneralPage() {
  const params = useParams();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const clientId = params.id;
  const isCreate = !clientId;
  const { data, isLoading, error } = useQuery({
    queryKey: ["client", clientId],
    queryFn: () => fetchClient(clientId as string),
    enabled: !isCreate,
  });

  const [name, setName] = useState("");
  const [description, setDescription] = useState("");
  const [logoUrl, setLogoUrl] = useState("");
  const [clientType, setClientType] = useState<ClientType>("private");
  const [status, setStatus] = useState<ClientStatus>("active");
  const [initialStatus, setInitialStatus] = useState<ClientStatus>("active");
  const [redirectUris, setRedirectUris] = useState("");

  // Public Key Registration States
  const [tokenEndpointAuthMethod, setTokenEndpointAuthMethod] =
    useState<TokenEndpointAuthMethod>("client_secret_basic");
  const [jwksSource, setJwksSource] = useState<"uri" | "inline">("inline");
  const [jwksUri, setJwksUri] = useState("");
  const [jwksText, setJwksText] = useState("");
  const [requestObjectSigningAlg, setRequestObjectSigningAlg] =
    useState("RS256");
  const [headlessLoginEnabled, setHeadlessLoginEnabled] = useState(false);

  const [scopes, setScopes] = useState<ScopeItem[]>(() => [
    {
      id: "1",
      name: "openid",
      description: t("msg.dev.clients.scopes.openid", "OIDC 인증 필수 스코프"),
      mandatory: true,
    },
    {
      id: "2",
      name: "profile",
      description: t("msg.dev.clients.scopes.profile", "기본 프로필 정보 접근"),
      mandatory: false,
    },
    {
      id: "3",
      name: "email",
      description: t("msg.dev.clients.scopes.email", "이메일 주소 접근"),
      mandatory: false,
    },
  ]);

  useEffect(() => {
    if (!data) return;
    const { client } = data;
    setName(client.name || client.id);
    setClientType(client.type);
    setStatus(client.status);
    setInitialStatus(client.status);

    const metadata = client.metadata ?? {};
    if (typeof metadata.description === "string")
      setDescription(metadata.description);
    if (typeof metadata.logo_url === "string") setLogoUrl(metadata.logo_url);

    const headlessEnabled = !!metadata.headless_login_enabled;
    setHeadlessLoginEnabled(headlessEnabled);

    const savedAuthMethod =
      client.tokenEndpointAuthMethod ||
      (client.type === "pkce" ? "none" : "client_secret_basic");
    const headlessAuthMethod = readMetadataString(
      metadata,
      "headless_token_endpoint_auth_method",
    );
    const selectedAuthMethod =
      headlessEnabled && isTokenEndpointAuthMethod(headlessAuthMethod)
        ? headlessAuthMethod
        : savedAuthMethod;
    if (isTokenEndpointAuthMethod(selectedAuthMethod)) {
      setTokenEndpointAuthMethod(selectedAuthMethod);
    }

    const headlessJwksUri = readMetadataString(metadata, "headless_jwks_uri");
    const headlessJwks = readMetadataObject(metadata, "headless_jwks");
    if (headlessJwksUri) {
      setJwksUri(headlessJwksUri);
      setJwksText("");
      setJwksSource("uri");
    } else if (headlessJwks) {
      setJwksText(JSON.stringify(headlessJwks, null, 2));
      setJwksUri("");
      setJwksSource("inline");
    } else if (client.jwksUri) {
      setJwksUri(client.jwksUri);
      setJwksText("");
      setJwksSource("uri");
    } else if (client.jwks) {
      setJwksText(
        typeof client.jwks === "string"
          ? client.jwks
          : JSON.stringify(client.jwks, null, 2),
      );
      setJwksUri("");
      setJwksSource("inline");
    } else {
      setJwksUri("");
      setJwksText("");
      setJwksSource("inline");
    }

    // Fallbacks from metadata if top-level fields are empty
    if (!client.tokenEndpointAuthMethod && !headlessEnabled) {
      const metaAuth = readMetadataString(
        metadata,
        "token_endpoint_auth_method",
      );
      if (isTokenEndpointAuthMethod(metaAuth)) {
        setTokenEndpointAuthMethod(metaAuth);
      }
    }

    if (!client.jwksUri && !client.jwks && !headlessEnabled) {
      const metaJwksUri = readMetadataString(metadata, "jwks_uri");
      if (metaJwksUri) {
        setJwksUri(metaJwksUri);
        setJwksSource("uri");
      }
    }

    const savedRequestObjectSigningAlg = readMetadataString(
      metadata,
      "request_object_signing_alg",
    );
    if (savedRequestObjectSigningAlg) {
      setRequestObjectSigningAlg(savedRequestObjectSigningAlg);
    } else if (savedAuthMethod === "private_key_jwt") {
      setRequestObjectSigningAlg("RS256");
    }

    const savedScopes = metadata.structured_scopes as ScopeItem[] | undefined;
    if (savedScopes && Array.isArray(savedScopes)) {
      setScopes(savedScopes);
    } else {
      setScopes(
        client.scopes.map((s, idx) => ({
          id: String(idx + 1),
          name: s,
          description: "",
          mandatory: s === "openid",
        })),
      );
    }
  }, [data]);

  const securityProfile: SecurityProfile =
    clientType === "pkce" ? "pkce" : "private";

  const handleSecurityProfileChange = (profile: SecurityProfile) => {
    setClientType(profile);
    if (profile === "pkce") {
      setTokenEndpointAuthMethod(
        headlessLoginEnabled ? "private_key_jwt" : "none",
      );
    } else {
      setTokenEndpointAuthMethod("client_secret_basic");
    }
  };

  const handleHeadlessToggle = (enabled: boolean) => {
    setHeadlessLoginEnabled(enabled);
    if (clientType === "pkce") {
      setTokenEndpointAuthMethod(enabled ? "private_key_jwt" : "none");
      if (enabled && requestObjectSigningAlg.trim() === "") {
        setRequestObjectSigningAlg("RS256");
      }
    }
  };

  const addScope = () => {
    const newId = String(Date.now());
    setScopes([
      ...scopes,
      { id: newId, name: "", description: "", mandatory: false },
    ]);
  };

  const updateScope = <K extends keyof ScopeItem>(
    id: string,
    field: K,
    value: ScopeItem[K],
  ) => {
    setScopes(
      scopes.map((scope) =>
        scope.id === id ? { ...scope, [field]: value } : scope,
      ),
    );
  };

  const removeScope = (id: string) => {
    setScopes(scopes.filter((s) => s.id !== id));
  };

  const handleStatusChange = (nextStatus: ClientStatus) => {
    setStatus(nextStatus);
    const statusLabel =
      nextStatus === "active"
        ? t("ui.common.status.active", "Active")
        : t("ui.common.status.inactive", "Inactive");
    toast(
      t(
        "msg.dev.clients.general.status_changed",
        "상태가 {{status}}로 변경되었습니다.",
        { status: statusLabel },
      ),
    );
  };

  // Convert on blur or change if desired, here we try to convert before validation
  const finalJwksText = tryConvertToJwks(jwksText);
  const validationErrors: string[] = [];
  const trimmedJwksUri = jwksUri.trim();
  const trimmedJwksText = finalJwksText.trim();
  const trimmedRequestObjectSigningAlg = requestObjectSigningAlg.trim();

  if (headlessLoginEnabled) {
    if (jwksSource === "uri") {
      if (!trimmedJwksUri) {
        validationErrors.push(
          t(
            "msg.dev.clients.general.public_key.validation.missing_jwks_uri",
            "JWKS URI를 입력해야 합니다.",
          ),
        );
      } else if (!isValidUrl(trimmedJwksUri)) {
        validationErrors.push(
          t(
            "msg.dev.clients.general.public_key.validation.invalid_jwks_uri",
            "JWKS URI 형식이 올바르지 않습니다.",
          ),
        );
      }
    } else if (jwksSource === "inline") {
      if (!trimmedJwksText) {
        validationErrors.push(
          t(
            "msg.dev.clients.general.public_key.validation.missing_jwks_inline",
            "공개키(JWKS 또는 SSH-RSA)를 입력해야 합니다.",
          ),
        );
      } else if (!isValidJson(trimmedJwksText)) {
        validationErrors.push(
          t(
            "msg.dev.clients.general.public_key.validation.invalid_jwks_inline",
            "입력값이 유효한 JSON(JWKS) 형식이 아닙니다. SSH-RSA의 경우 'ssh-rsa'로 시작해야 합니다.",
          ),
        );
      }
    }

    if (trimmedRequestObjectSigningAlg === "") {
      validationErrors.push(
        t(
          "msg.dev.clients.general.public_key.validation.headless_requires_alg",
          "Request Object Signing Algorithm (예: RS256)을 입력해야 합니다.",
        ),
      );
    }
  }

  const hasValidationErrors = validationErrors.length > 0;

  const mutation = useMutation({
    mutationFn: async () => {
      const scopeNames = scopes.map((scope) => scope.name).filter(Boolean);

      let finalJwks: ClientUpsertRequest["jwks"];
      if (jwksSource === "inline" && trimmedJwksText) {
        try {
          finalJwks = JSON.parse(trimmedJwksText);
        } catch (e) {
          throw new Error("Invalid Public Key Format");
        }
      }

      const effectiveTokenEndpointAuthMethod =
        clientType === "pkce" && headlessLoginEnabled
          ? "none"
          : tokenEndpointAuthMethod;

      const payload: ClientUpsertRequest = {
        name,
        type: clientType,
        scopes: scopeNames,
        tokenEndpointAuthMethod: effectiveTokenEndpointAuthMethod,
        jwksUri:
          effectiveTokenEndpointAuthMethod === "private_key_jwt" &&
          jwksSource === "uri"
            ? trimmedJwksUri
            : undefined,
        jwks:
          effectiveTokenEndpointAuthMethod === "private_key_jwt"
            ? finalJwks
            : undefined,
        metadata: {
          description,
          logo_url: logoUrl,
          structured_scopes: scopes,
          token_endpoint_auth_method: effectiveTokenEndpointAuthMethod,
          request_object_signing_alg: trimmedRequestObjectSigningAlg,
          headless_login_enabled: headlessLoginEnabled,
          headless_token_endpoint_auth_method:
            clientType === "pkce" && headlessLoginEnabled
              ? tokenEndpointAuthMethod
              : undefined,
          headless_jwks_uri:
            clientType === "pkce" &&
            headlessLoginEnabled &&
            jwksSource === "uri"
              ? trimmedJwksUri
              : undefined,
          headless_jwks:
            clientType === "pkce" &&
            headlessLoginEnabled &&
            jwksSource === "inline"
              ? finalJwks
              : undefined,
        },
      };

      if (isCreate) {
        payload.status = status;
        payload.redirectUris = redirectUris
          .split(",")
          .map((uri) => uri.trim())
          .filter(Boolean);
        return createClient(payload);
      }

      const updated = await updateClient(clientId as string, payload);
      if (status !== initialStatus) {
        await updateClientStatus(clientId as string, status);
      }
      return updated;
    },
    onSuccess: (result) => {
      queryClient.invalidateQueries({ queryKey: ["clients"] });
      if (status !== initialStatus) {
        setInitialStatus(status);
      }
      if (result?.client?.id) {
        navigate(`/clients/${result.client.id}/settings`);
      }
      alert(t("msg.dev.clients.general.saved", "설정이 저장되었습니다."));
    },
    onError: (err) => {
      const errorMessage =
        (err as AxiosError<{ error?: string }>).response?.data?.error ??
        (err as Error)?.message ??
        t("msg.common.unknown_error", "unknown error");
      alert(
        t(
          "msg.dev.clients.general.save_error",
          "저장에 실패했습니다: {{error}}",
          {
            error: errorMessage,
          },
        ),
      );
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) => deleteClient(id),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["clients"] });
      alert(t("msg.dev.clients.deleted", "앱이 삭제되었습니다."));
      navigate("/clients");
    },
    onError: (err) => {
      const errorMessage =
        (err as AxiosError<{ error?: string }>).response?.data?.error ??
        (err as Error)?.message;
      alert(
        t("msg.dev.clients.delete_error", "삭제 실패: {{error}}", {
          error: errorMessage,
        }),
      );
    },
  });

  const handleDelete = () => {
    if (
      clientId &&
      window.confirm(
        t(
          "msg.dev.clients.delete_confirm",
          "정말로 이 앱을 삭제하시습니까? 이 작업은 되돌릴 수 없습니다.",
        ),
      )
    ) {
      deleteMutation.mutate(clientId);
    }
  };

  if (!isCreate && isLoading) {
    return (
      <div className="p-8 text-center">
        {t("msg.dev.clients.general.loading", "Loading client...")}
      </div>
    );
  }
  if (!isCreate && (error || !data)) {
    const errMsg =
      (error as AxiosError<{ error?: string }>).response?.data?.error ??
      (error as Error)?.message;
    return (
      <div className="p-8 text-center text-red-500">
        {t(
          "msg.dev.clients.general.load_error",
          "Error loading client: {{error}}",
          {
            error: errMsg || t("msg.common.unknown_error", "unknown error"),
          },
        )}
      </div>
    );
  }

  const publicKeyStatusTone = headlessLoginEnabled
    ? hasValidationErrors
      ? "border-destructive/40 bg-destructive/5"
      : "border-primary/30 bg-primary/5"
    : "border-border bg-muted/20";

  const displayName = isCreate
    ? t("ui.dev.clients.general.display_new", "새 클라이언트")
    : data?.client?.name || data?.client?.id;

  return (
    <div className="space-y-8">
      <header className="space-y-4">
        <div className="flex flex-wrap items-start justify-between gap-4">
          <div className="space-y-2">
            <nav className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
              <Link to="/" className="hover:text-primary">
                {t("ui.dev.clients.consents.breadcrumb.home", "Home")}
              </Link>
              <span>/</span>
              <Link to="/clients" className="hover:text-primary">
                {t("ui.dev.clients.consents.breadcrumb.clients", "Apps")}
              </Link>
              <span>/</span>
              <span>{displayName}</span>
              {!isCreate && (
                <>
                  <span>/</span>
                  <span className="text-foreground font-semibold">
                    {t("ui.dev.clients.details.tab.settings", "Settings")}
                  </span>
                </>
              )}
            </nav>
            <div className="flex items-center gap-2">
              <Button variant="ghost" size="icon" asChild>
                <Link to={isCreate ? "/clients" : `/clients/${clientId}`}>
                  <ArrowLeft className="h-4 w-4" />
                </Link>
              </Button>
              <div>
                <h1 className="text-3xl font-black leading-tight">
                  {isCreate
                    ? t("ui.dev.clients.general.title_create", "Create Client")
                    : t("ui.dev.clients.general.title_edit", "Client Settings")}
                </h1>
                <p className="text-muted-foreground">
                  {t(
                    "ui.dev.clients.general.subtitle",
                    "앱 정보, 권한 스코프, 보안 설정을 관리합니다.",
                  )}
                </p>
              </div>
            </div>
          </div>
          {!isCreate && (
            <Badge
              variant={status === "active" ? "info" : "muted"}
              className="px-3 py-1 text-xs uppercase"
            >
              {status === "active"
                ? t("ui.common.status.active", "Active")
                : t("ui.common.status.inactive", "Inactive")}
            </Badge>
          )}
        </div>
        <div className="flex gap-6 overflow-x-auto border-b border-border pb-3 text-sm font-bold">
          {!isCreate && (
            <>
              <Link
                to={`/clients/${clientId}`}
                className="whitespace-nowrap border-b-2 border-transparent text-muted-foreground hover:text-foreground"
              >
                {t("ui.dev.clients.details.tab.connection", "Federation")}
              </Link>
              <Link
                to={`/clients/${clientId}/consents`}
                className="whitespace-nowrap border-b-2 border-transparent text-muted-foreground hover:text-foreground"
              >
                {t("ui.dev.clients.details.tab.consents", "Consent & Users")}
              </Link>
              <span className="whitespace-nowrap border-b-2 border-primary pb-1 text-primary">
                {t("ui.dev.clients.details.tab.settings", "Settings")}
              </span>
            </>
          )}
        </div>
      </header>

      {/* 1. Application Identity */}
      <div className="glass-panel p-6">
        <div className="flex items-center justify-between mb-6">
          <div>
            <CardTitle className="text-xl font-bold mb-2">
              {t(
                "ui.dev.clients.general.identity.title",
                "Application Identity",
              )}
            </CardTitle>
            <CardDescription>
              {t(
                "msg.dev.clients.general.identity.subtitle",
                "앱 이름과 설명, 로고를 설정합니다.",
              )}
            </CardDescription>
          </div>
        </div>
        <div className="grid gap-8 md:grid-cols-2">
          <div className="space-y-5">
            <div className="space-y-2">
              <Label className="text-sm font-semibold">
                {t("ui.dev.clients.general.identity.name", "앱 이름")}{" "}
                <span className="text-destructive">*</span>
              </Label>
              <Input
                value={name}
                onChange={(e) => setName(e.target.value)}
                placeholder={t(
                  "ui.dev.clients.general.identity.name_placeholder",
                  "My Awesome Application",
                )}
              />
            </div>
            <div className="space-y-2">
              <Label className="text-sm font-semibold">
                {t(
                  "ui.dev.clients.general.identity.description",
                  "Description",
                )}
              </Label>
              <Textarea
                rows={3}
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                placeholder={t(
                  "ui.dev.clients.general.identity.description_placeholder",
                  "앱에 대한 간단한 설명을 입력하세요.",
                )}
              />
            </div>
          </div>
          <div className="space-y-5">
            <div className="space-y-2">
              <Label className="text-sm font-semibold">
                {t("ui.dev.clients.general.identity.logo", "App Logo URL")}
              </Label>
              <div className="flex gap-4">
                <div className="flex-1 space-y-2">
                  <Input
                    value={logoUrl}
                    onChange={(e) => setLogoUrl(e.target.value)}
                    placeholder={t(
                      "ui.dev.clients.general.identity.logo_placeholder",
                      "https://example.com/logo.png",
                    )}
                  />
                  <p className="text-xs text-muted-foreground">
                    {t(
                      "msg.dev.clients.general.identity.logo_help",
                      "인증 화면에 표시될 PNG/SVG URL입니다.",
                    )}
                  </p>
                </div>
                <div className="flex h-20 w-20 items-center justify-center rounded-lg border-2 border-dashed border-border bg-muted/40 shrink-0">
                  {logoUrl ? (
                    <img
                      src={logoUrl}
                      alt={t(
                        "ui.dev.clients.general.identity.logo_preview",
                        "Logo Preview",
                      )}
                      className="h-full w-full object-contain"
                    />
                  ) : (
                    <Upload className="h-5 w-5 text-muted-foreground" />
                  )}
                </div>
              </div>
            </div>

            <div className="space-y-2">
              <Label className="text-sm font-semibold">
                {t("ui.dev.clients.table.status", "상태")}
              </Label>
              <div className="flex gap-2">
                <Button
                  type="button"
                  size="sm"
                  variant={status === "active" ? "default" : "outline"}
                  onClick={() => handleStatusChange("active")}
                >
                  {t("ui.common.status.active", "활성")}
                </Button>
                <Button
                  type="button"
                  size="sm"
                  variant={status === "inactive" ? "default" : "outline"}
                  onClick={() => handleStatusChange("inactive")}
                >
                  {t("ui.common.status.inactive", "비활성")}
                </Button>
              </div>
            </div>
          </div>
        </div>
      </div>

      {/* 2. Scopes */}
      <Card className="glass-panel">
        <CardHeader className="flex flex-row items-center justify-between space-y-0 pb-4">
          <div>
            <CardTitle className="text-xl font-bold">
              {t("ui.dev.clients.general.scopes.title", "Scopes")}
            </CardTitle>
            <CardDescription>
              {t(
                "msg.dev.clients.general.scopes.subtitle",
                "이 클라이언트가 요청할 수 있는 권한 범위를 정의합니다.",
              )}
            </CardDescription>
          </div>
          <Button
            variant="outline"
            size="sm"
            onClick={addScope}
            className="gap-2"
          >
            <Plus className="h-4 w-4" />
            {t("ui.dev.clients.general.scopes.add", "Scope 추가")}
          </Button>
        </CardHeader>
        <CardContent className="space-y-6">
          {isCreate && (
            <div className="space-y-2 border-b border-border pb-6 mb-6">
              <Label className="text-sm font-semibold">
                {t("ui.dev.clients.general.redirect.label", "Redirect URIs")}{" "}
                <span className="text-destructive">*</span>
              </Label>
              <Textarea
                value={redirectUris}
                onChange={(e) => setRedirectUris(e.target.value)}
                placeholder={t(
                  "ui.dev.clients.general.redirect.placeholder",
                  "https://app.example.com/callback, http://localhost:3000/auth/callback (콤마로 구분)",
                )}
                className="font-mono text-sm"
              />
              <p className="text-xs text-muted-foreground">
                {t(
                  "msg.dev.clients.general.redirect.help",
                  "인증 후 리다이렉트될 URI를 입력하세요. 생성 후 Connection 탭에서 수정 가능합니다.",
                )}
              </p>
            </div>
          )}

          <div className="rounded-md border border-border overflow-hidden">
            <table className="w-full text-sm">
              <thead className="bg-muted/50 border-b border-border text-xs uppercase tracking-wider text-muted-foreground">
                <tr>
                  <th className="px-4 py-3 text-left font-bold">
                    {t(
                      "ui.dev.clients.general.scopes.table.name",
                      "Scope Name",
                    )}
                  </th>
                  <th className="px-4 py-3 text-left font-bold">
                    {t(
                      "ui.dev.clients.general.scopes.table.description",
                      "Description",
                    )}
                  </th>
                  <th className="px-4 py-3 text-center font-bold">
                    {t(
                      "ui.dev.clients.general.scopes.table.mandatory",
                      "Mandatory",
                    )}
                  </th>
                  <th className="px-4 py-3 text-right font-bold">
                    {t("ui.dev.clients.general.scopes.table.delete", "Delete")}
                  </th>
                </tr>
              </thead>
              <tbody className="divide-y divide-border">
                {scopes.map((s) => (
                  <tr
                    key={s.id}
                    className="hover:bg-muted/30 transition-colors"
                  >
                    <td className="px-4 py-3">
                      <Input
                        value={s.name}
                        onChange={(e) =>
                          updateScope(s.id, "name", e.target.value)
                        }
                        className="h-8 font-mono text-xs"
                        placeholder={t(
                          "ui.dev.clients.general.scopes.name_placeholder",
                          "e.g. profile",
                        )}
                      />
                    </td>
                    <td className="px-4 py-3">
                      <Input
                        value={s.description}
                        onChange={(e) =>
                          updateScope(s.id, "description", e.target.value)
                        }
                        className="h-8 text-xs"
                        placeholder={t(
                          "ui.dev.clients.general.scopes.description_placeholder",
                          "권한에 대한 설명",
                        )}
                      />
                    </td>
                    <td className="px-4 py-3 text-center">
                      <div className="flex justify-center">
                        <Switch
                          checked={s.mandatory}
                          onCheckedChange={(checked) =>
                            updateScope(s.id, "mandatory", checked)
                          }
                        />
                      </div>
                    </td>
                    <td className="px-4 py-3 text-right">
                      <Button
                        variant="ghost"
                        size="icon"
                        onClick={() => removeScope(s.id)}
                        className="h-8 w-8 text-muted-foreground hover:text-destructive"
                      >
                        <Trash2 className="h-4 w-4" />
                      </Button>
                    </td>
                  </tr>
                ))}
                {scopes.length === 0 && (
                  <tr>
                    <td
                      colSpan={4}
                      className="px-4 py-8 text-center text-muted-foreground"
                    >
                      {t(
                        "msg.dev.clients.general.scopes.empty",
                        "등록된 스코프가 없습니다.",
                      )}
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </CardContent>
      </Card>

      {/* 3. Security Settings */}
      <Card className="glass-panel">
        <CardHeader className="pb-3">
          <CardTitle className="text-xl font-bold">
            {t("ui.dev.clients.general.security.title", "보안 설정")}
          </CardTitle>
          <CardDescription>
            {t(
              "msg.dev.clients.general.security.subtitle",
              "클라이언트 유형을 선택하세요. 보안 수준에 따라 인증 방식이 달라집니다.",
            )}
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="grid gap-4 md:grid-cols-2">
            <label
              className={cn(
                "relative flex cursor-pointer flex-col gap-1 rounded-xl border-2 p-4 transition",
                securityProfile === "private"
                  ? "border-primary bg-primary/5"
                  : "border-border bg-card hover:border-muted-foreground/40",
              )}
            >
              <input
                className="sr-only"
                type="radio"
                name="security-profile"
                checked={securityProfile === "private"}
                onChange={() => handleSecurityProfileChange("private")}
              />
              <span className="flex items-center gap-2 text-sm font-bold uppercase text-foreground">
                <Shield className="h-4 w-4 text-primary" />
                {t(
                  "ui.dev.clients.general.security.private",
                  "Server side App",
                )}
              </span>
              <span className="text-xs text-muted-foreground">
                {t(
                  "msg.dev.clients.general.security.private_help",
                  "서버 사이드 앱(예: Node.js, Java)처럼 비밀키를 안전하게 보관 가능한 경우.",
                )}
              </span>
              <span className="absolute right-4 top-4 text-primary">
                {securityProfile === "private" ? "✓" : ""}
              </span>
            </label>

            <label
              className={cn(
                "relative flex cursor-pointer flex-col gap-1 rounded-xl border-2 p-4 transition",
                securityProfile === "pkce"
                  ? "border-primary bg-primary/5"
                  : "border-border bg-card hover:border-muted-foreground/40",
              )}
            >
              <input
                className="sr-only"
                type="radio"
                name="security-profile"
                checked={securityProfile === "pkce"}
                onChange={() => handleSecurityProfileChange("pkce")}
              />
              <span className="flex items-center gap-2 text-sm font-bold uppercase text-foreground">
                <Sparkles className="h-4 w-4" />
                {t("ui.dev.clients.general.security.pkce", "PKCE")}
              </span>
              <span className="text-xs text-muted-foreground">
                {t(
                  "msg.dev.clients.general.security.pkce_help",
                  "SPA/모바일 앱처럼 비밀키 보관이 어려운 경우. PKCE를 기본 사용합니다.",
                )}
              </span>
              <span className="absolute right-4 top-4 text-primary">
                {securityProfile === "pkce" ? "✓" : ""}
              </span>

              {securityProfile === "pkce" && (
                <div
                  className="mt-4 pt-4 border-t border-primary/20 flex items-center justify-between"
                  onClick={(e) => e.stopPropagation()}
                  onKeyDown={(e) => e.stopPropagation()}
                >
                  <div className="space-y-0.5">
                    <Label
                      className="text-xs font-bold cursor-pointer"
                      htmlFor="headless-login-toggle"
                    >
                      {t(
                        "ui.dev.clients.general.security.headless_login_enable",
                        "Headless Login (자체 로그인 UI 사용)",
                      )}
                    </Label>
                    <p className="text-[10px] text-muted-foreground">
                      {t(
                        "ui.dev.clients.general.security.headless_login_enable_help",
                        "Baron SSO 로그인 창을 거치지 않고 애플리케이션 내의 자체 로그인 화면을 직접 구현하고 싶은 경우 활성화합니다.",
                      )}
                    </p>
                  </div>
                  <Switch
                    id="headless-login-toggle"
                    checked={headlessLoginEnabled}
                    onCheckedChange={handleHeadlessToggle}
                  />
                </div>
              )}
            </label>
          </div>
        </CardContent>
      </Card>

      {/* 4. Public Key Registration (Headless Login) */}
      {clientType === "pkce" && headlessLoginEnabled && (
        <Card className="glass-panel border-primary/20">
          <CardHeader className="pb-3">
            <div className="flex flex-wrap items-start justify-between gap-3">
              <div>
                <CardTitle className="text-xl font-bold flex items-center gap-2">
                  {t(
                    "ui.dev.clients.general.public_key.title",
                    "Public Key Registration",
                  )}
                </CardTitle>
                <CardDescription>
                  {t(
                    "msg.dev.clients.general.public_key.subtitle",
                    "Headless Login 판정에 필요한 공개키와 관련 설정을 관리합니다.",
                  )}
                </CardDescription>
              </div>
            </div>
          </CardHeader>
          <CardContent className="space-y-6">
            <div className={cn("rounded-xl border p-4", publicKeyStatusTone)}>
              <div className="flex items-center justify-between">
                <div>
                  <Label className="text-sm font-bold text-foreground">
                    {t(
                      "ui.dev.clients.general.public_key.headless_toggle",
                      "Headless Login 허용 여부",
                    )}
                  </Label>
                  <p className="mt-1 text-xs text-muted-foreground">
                    {t(
                      "msg.dev.clients.general.public_key.headless_help",
                      "애플리케이션 고유의 디자인으로 로그인 화면을 구성할 수 있습니다. 실제 아이디/비밀번호 확인 및 보안 검증 로직은 Baron API를 통해 백그라운드에서 처리됩니다.",
                    )}
                  </p>
                </div>
                <Badge
                  variant="default"
                  className="bg-primary/20 text-primary border-primary/30"
                >
                  {t("ui.common.enabled", "Enabled")}
                </Badge>
              </div>
            </div>

            <div className="grid gap-6 md:grid-cols-2">
              <div className="space-y-3">
                <Label className="text-sm font-semibold">
                  {t(
                    "ui.dev.clients.general.public_key.request_object_alg",
                    "Request Object Signing Algorithm",
                  )}
                  <span className="text-destructive ml-1">*</span>
                </Label>
                <Input
                  value={requestObjectSigningAlg}
                  onChange={(e) => setRequestObjectSigningAlg(e.target.value)}
                  placeholder={t(
                    "ui.dev.clients.general.public_key.request_object_alg_placeholder",
                    "예: RS256",
                  )}
                />
                <p className="text-xs text-muted-foreground">
                  {t(
                    "msg.dev.clients.general.public_key.request_object_alg_help",
                    "Headless Login을 사용할 때 JAR(Request Object) 서명 검증에 사용할 알고리즘을 명시합니다.",
                  )}
                </p>
              </div>
            </div>

            <div className="space-y-4 rounded-xl border border-border bg-muted/5 p-4">
              <div className="space-y-1 pb-2 border-b border-border/50">
                <Label className="text-sm font-bold">
                  {t(
                    "ui.dev.clients.general.public_key.source",
                    "Public Key Source",
                  )}
                </Label>
                <p className="text-xs text-muted-foreground">
                  {t(
                    "msg.dev.clients.general.public_key.source_help",
                    "OIDC 검증을 위한 공개키 제공 방식을 선택합니다. (운영 환경에서는 JWKS URI 사용을 권장합니다)",
                  )}
                </p>
              </div>

              <div className="flex gap-4">
                <label className="flex items-center gap-2 text-sm">
                  <input
                    type="radio"
                    name="jwksSource"
                    checked={jwksSource === "inline"}
                    onChange={() => setJwksSource("inline")}
                    className="accent-primary"
                  />
                  <span>Inline Public Key</span>
                </label>
                <label className="flex items-center gap-2 text-sm">
                  <input
                    type="radio"
                    name="jwksSource"
                    checked={jwksSource === "uri"}
                    onChange={() => setJwksSource("uri")}
                    className="accent-primary"
                  />
                  <span>JWKS URI</span>
                </label>
              </div>

              {jwksSource === "uri" && (
                <div className="space-y-2 animate-in fade-in slide-in-from-top-2">
                  <Label className="text-sm font-semibold">
                    {t(
                      "ui.dev.clients.general.public_key.jwks_uri",
                      "JWKS URI",
                    )}
                    <span className="text-destructive ml-1">*</span>
                  </Label>
                  <Input
                    value={jwksUri}
                    onChange={(e) => setJwksUri(e.target.value)}
                    placeholder={t(
                      "ui.dev.clients.general.public_key.jwks_uri_placeholder",
                      "https://rp.example.com/.well-known/jwks.json",
                    )}
                  />
                  <p className="text-xs text-muted-foreground">
                    {t(
                      "msg.dev.clients.general.public_key.jwks_uri_help",
                      "RP backend가 제공하는 공개키 endpoint URL을 입력하세요.",
                    )}
                  </p>
                </div>
              )}

              {jwksSource === "inline" && (
                <div className="space-y-2 animate-in fade-in slide-in-from-top-2">
                  <Label className="text-sm font-semibold">
                    {t(
                      "ui.dev.clients.general.public_key.jwks_inline",
                      "JWKS 또는 OpenSSH 공개키",
                    )}
                    <span className="text-destructive ml-1">*</span>
                  </Label>
                  <Textarea
                    rows={8}
                    value={jwksText}
                    onChange={(e) => setJwksText(e.target.value)}
                    placeholder={t(
                      "ui.dev.clients.general.public_key.jwks_inline_placeholder",
                      "JWKS (JSON) 또는 'ssh-rsa AAA...' 형식의 공개키를 붙여넣으세요.",
                    )}
                    className="font-mono text-xs leading-tight"
                  />
                  <p className="text-xs text-muted-foreground">
                    {t(
                      "msg.dev.clients.general.public_key.jwks_inline_help",
                      "OIDC 표준인 JWKS(JSON) 형식을 권장하지만, SSH-RSA 공개키를 입력하면 자동으로 변환하여 저장합니다.",
                    )}
                  </p>
                </div>
              )}
            </div>

            {hasValidationErrors && (
              <div className="rounded-xl border border-destructive/40 bg-destructive/5 p-4 animate-in fade-in">
                <p className="text-sm font-semibold text-destructive flex items-center gap-2">
                  <span>⚠️</span>
                  {t(
                    "ui.dev.clients.general.public_key.validation_title",
                    "저장 전 확인 필요",
                  )}
                </p>
                <ul className="mt-2 list-disc space-y-1 pl-6 text-sm text-destructive">
                  {validationErrors.map((errorMessage) => (
                    <li key={errorMessage}>{errorMessage}</li>
                  ))}
                </ul>
              </div>
            )}
          </CardContent>
        </Card>
      )}

      <div className="flex items-center justify-between border-t border-border pt-4">
        <div>
          {!isCreate && (
            <Button
              variant="destructive"
              className="gap-2"
              onClick={handleDelete}
              disabled={deleteMutation.isPending}
            >
              <Trash2 className="h-4 w-4" />
              {deleteMutation.isPending
                ? t("msg.common.requesting", "요청 중...")
                : t("ui.common.delete", "삭제")}
            </Button>
          )}
        </div>
        <div className="flex flex-col-reverse sm:flex-row sm:justify-end gap-2">
          <Button variant="outline" onClick={() => navigate("/clients")}>
            {t("ui.common.cancel", "취소")}
          </Button>
          <Button
            onClick={() => mutation.mutate()}
            disabled={
              mutation.isPending ||
              isLoading ||
              name.trim() === "" ||
              (isCreate && redirectUris.trim() === "") ||
              hasValidationErrors
            }
            className="shadow-lg shadow-primary/20"
          >
            {mutation.isPending ? (
              <div className="h-4 w-4 border-2 border-white/30 border-t-white rounded-full animate-spin mr-2" />
            ) : (
              <Save size={16} className="mr-2" />
            )}
            {mutation.isPending
              ? t("msg.common.saving", "저장 중...")
              : isCreate
                ? t("ui.dev.clients.general.create", "클라이언트 생성")
                : t("ui.common.save", "저장")}
          </Button>
        </div>
      </div>
    </div>
  );
}

export default ClientGeneralPage;
