import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import {
  Eye,
  EyeOff,
  Link2,
  RefreshCw,
  Save,
  Shield,
  ShieldHalf,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { Link, useParams } from "react-router-dom";
import { PageHeader } from "../../../../common/core/components/page";
import { Badge } from "../../components/ui/badge";
import { Button } from "../../components/ui/button";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "../../components/ui/card";
import { CopyButton } from "../../components/ui/copy-button";
import { Label } from "../../components/ui/label";
import { Separator } from "../../components/ui/separator";
import {
  Table,
  TableBody,
  TableCell,
  TableRow,
} from "../../components/ui/table";
import { Textarea } from "../../components/ui/textarea";
import { toast } from "../../components/ui/use-toast";
import {
  fetchClient,
  rotateClientSecret,
  updateClient,
} from "../../lib/devApi";
import { t } from "../../lib/i18n";
import { cn } from "../../lib/utils";
import { ClientDetailTabs } from "./ClientDetailTabs";
import { canDisplayClientSecret } from "./clientSecretPolicy";

function ClientDetailsPage() {
  const params = useParams();
  const queryClient = useQueryClient();
  const clientId = params.id ?? "";

  const { data, error, isLoading } = useQuery({
    queryKey: ["client", clientId],
    queryFn: () => fetchClient(clientId),
    enabled: clientId.length > 0,
  });

  const [redirectUris, setRedirectUris] = useState("");
  const [showSecret, setShowSecret] = useState(false);
  const redirectUrisHydratedRef = useRef(false);

  useEffect(() => {
    if (
      !redirectUrisHydratedRef.current &&
      data?.client?.redirectUris &&
      redirectUris === ""
    ) {
      setRedirectUris(data.client.redirectUris.join(", "));
      redirectUrisHydratedRef.current = true;
    }
  }, [data, redirectUris]);

  const mutation = useMutation({
    mutationFn: () => {
      const uriList = redirectUris
        .split(",")
        .map((u) => u.trim())
        .filter(Boolean);
      return updateClient(clientId, { redirectUris: uriList });
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["client", clientId] });
      toast(
        t(
          "msg.dev.clients.details.redirect_saved",
          "Redirect URIs가 저장되었습니다.",
        ),
      );
    },
    onError: (err) => {
      const axiosError = err as AxiosError<{ error?: string }>;
      if (axiosError.response?.status === 403) {
        toast(
          t(
            "msg.dev.clients.details.save_forbidden",
            "이 RP 설정을 수정할 권한이 없습니다.\n관리자에게 RP 일반 설정 또는 RP 관리자 관계 부여를 요청해 주세요.",
          ),
          "error",
        );
        return;
      }

      toast(
        t("msg.dev.clients.details.save_error", "저장 실패: {{error}}", {
          error:
            axiosError.response?.data?.error ??
            (err as Error).message ??
            t("msg.common.unknown_error", "unknown error"),
        }),
        "error",
      );
    },
  });

  const rotateMutation = useMutation({
    mutationFn: () => rotateClientSecret(clientId),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["client", clientId] });
      toast(
        t(
          "msg.dev.clients.details.secret_rotated",
          "Client Secret이 재발급되었습니다.",
        ),
      );
      setShowSecret(true); // 재발급 후 바로 보여줌
    },
    onError: (err) => {
      toast(
        t("msg.dev.clients.details.rotate_error", "재발급 실패: {{error}}", {
          error: (err as Error).message,
        }),
        "error",
      );
    },
  });

  const handleRotateSecret = () => {
    if (
      window.confirm(
        t(
          "msg.dev.clients.details.rotate_confirm",
          "경고: Client Secret을 재발급하면 기존 시크릿은 즉시 무효화됩니다.\n연동된 애플리케이션이 중단될 수 있습니다. 계속하시겠습니까?",
        ),
      )
    ) {
      rotateMutation.mutate();
    }
  };

  if (!clientId) {
    return (
      <div className="p-8 text-center">
        {t("msg.dev.clients.details.missing_id", "Client ID가 필요합니다.")}
      </div>
    );
  }

  if (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.details.load_error",
          "Error loading app: {{error}}",
          { error: errMsg || t("msg.common.unknown_error", "unknown error") },
        )}
      </div>
    );
  }

  if (isLoading && !data) {
    return (
      <div className="p-8 text-center">
        {t("msg.dev.clients.details.loading", "Loading app details...")}
      </div>
    );
  }

  const client = data?.client;
  if (!client) {
    return null;
  }
  const endpointValues = data?.endpoints ?? {
    discovery: "-",
    issuer: "-",
    authorization: "-",
    token: "-",
    userinfo: "-",
  };
  const endpoints = [
    {
      labelKey: "ui.dev.clients.details.endpoint.discovery",
      labelFallback: "Discovery Endpoint",
      value: endpointValues.discovery,
    },
    {
      labelKey: "ui.dev.clients.details.endpoint.issuer",
      labelFallback: "Issuer URL",
      value: endpointValues.issuer,
    },
    {
      labelKey: "ui.dev.clients.details.endpoint.authorization",
      labelFallback: "Authorization Endpoint",
      value: endpointValues.authorization,
    },
    {
      labelKey: "ui.dev.clients.details.endpoint.token",
      labelFallback: "Token Endpoint",
      value: endpointValues.token,
    },
    {
      labelKey: "ui.dev.clients.details.endpoint.userinfo",
      labelFallback: "UserInfo Endpoint",
      value: endpointValues.userinfo,
    },
  ];

  const hasClientSecret = canDisplayClientSecret(client);
  const secretPlaceholder = "SECRET_NOT_AVAILABLE";
  const clientSecret = hasClientSecret
    ? client?.clientSecret || secretPlaceholder
    : t("ui.common.na", "N/A");
  const displaySecret = !hasClientSecret
    ? t(
        "msg.dev.clients.details.secret_not_applicable",
        "PKCE 앱에는 Client Secret이 없습니다.",
      )
    : clientSecret === secretPlaceholder
      ? t("msg.dev.clients.details.secret_unavailable", "SECRET_NOT_AVAILABLE")
      : clientSecret;

  return (
    <div className="space-y-8">
      <div className="space-y-3">
        <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>{client?.name || clientId}</span>
          <span>/</span>
          <span className="text-foreground font-semibold">
            {t("ui.dev.clients.details.tab.connection", "Federation")}
          </span>
        </nav>
        <PageHeader
          icon={<ShieldHalf size={20} />}
          title={client?.name || client?.id || clientId}
          description={t(
            "msg.dev.clients.details.subtitle",
            "Manage OIDC credentials and endpoints.",
          )}
          actions={
            <Badge
              variant={client?.status === "active" ? "info" : "muted"}
              className="px-3 py-1 text-xs uppercase"
            >
              {client?.status === "active"
                ? t("ui.common.status.active", "Active")
                : client?.status === "inactive"
                  ? t("ui.common.status.inactive", "Inactive")
                  : t("msg.common.loading", "Loading...")}
            </Badge>
          }
        />
        <ClientDetailTabs activeTab="connection" clientId={clientId} />
      </div>

      <div className="grid gap-8 lg:grid-cols-2">
        <div className="space-y-6">
          <div className="space-y-4">
            <h2 className="text-xl font-bold">
              {t(
                "ui.dev.clients.details.credentials.title",
                "Client Credentials",
              )}
            </h2>
            <Card className="glass-panel">
              <CardContent className="flex flex-col gap-4 p-6">
                <div>
                  <p className="text-xs font-bold uppercase tracking-widest text-muted-foreground">
                    {t(
                      "ui.dev.clients.details.credentials.client_id",
                      "Client ID",
                    )}
                  </p>
                  <div className="flex items-center justify-between gap-2">
                    <p className="font-mono text-lg truncate">
                      {client?.id || clientId}
                    </p>
                    <CopyButton
                      value={client?.id || clientId}
                      onCopy={() =>
                        toast(
                          t(
                            "msg.dev.clients.details.copy_client_id",
                            "Client ID가 복사되었습니다.",
                          ),
                        )
                      }
                    />
                  </div>
                </div>

                <Separator />

                <div>
                  <p className="text-xs font-bold uppercase tracking-widest text-muted-foreground">
                    {t(
                      "ui.dev.clients.details.credentials.client_secret",
                      "Client Secret",
                    )}
                  </p>
                  <div className="flex items-center justify-between gap-2">
                    <p
                      className={cn(
                        "font-mono text-lg",
                        !showSecret && "tracking-widest",
                      )}
                    >
                      {showSecret ? displaySecret : "••••••••••••••••"}
                    </p>
                    <div className="flex gap-2 shrink-0">
                      {hasClientSecret ? (
                        <>
                          <Button
                            variant="secondary"
                            size="icon"
                            onClick={() => setShowSecret(!showSecret)}
                            aria-label={
                              showSecret
                                ? t(
                                    "ui.dev.clients.details.secret.hide",
                                    "비밀키 숨기기",
                                  )
                                : t(
                                    "ui.dev.clients.details.secret.show",
                                    "비밀키 보기",
                                  )
                            }
                          >
                            {showSecret ? (
                              <EyeOff className="h-4 w-4" />
                            ) : (
                              <Eye className="h-4 w-4" />
                            )}
                          </Button>
                          <Button
                            variant="secondary"
                            size="icon"
                            onClick={handleRotateSecret}
                            disabled={rotateMutation.isPending}
                            title={t(
                              "ui.dev.clients.details.secret.rotate",
                              "비밀키 재발급 (Rotate)",
                            )}
                          >
                            <RefreshCw
                              className={cn(
                                "h-4 w-4",
                                rotateMutation.isPending && "animate-spin",
                              )}
                            />
                          </Button>
                          <CopyButton
                            value={clientSecret}
                            disabled={
                              !showSecret && clientSecret === secretPlaceholder
                            }
                            onCopy={() =>
                              toast(
                                t(
                                  "msg.dev.clients.details.copy_client_secret",
                                  "Client Secret이 복사되었습니다.",
                                ),
                              )
                            }
                          />
                        </>
                      ) : null}
                    </div>
                  </div>
                  {!hasClientSecret ? (
                    <p className="mt-2 text-sm text-muted-foreground">
                      {t(
                        "msg.dev.clients.details.secret_not_applicable",
                        "PKCE 앱에는 Client Secret이 없습니다.",
                      )}
                    </p>
                  ) : null}
                </div>
              </CardContent>
            </Card>
          </div>

          <div className="space-y-4">
            <div className="flex items-center gap-2">
              <h2 className="text-xl font-bold">
                {t("ui.dev.clients.details.endpoints.title", "OIDC 엔드포인트")}
              </h2>
              <Badge variant="muted" className="gap-1">
                <Link2 className="h-3 w-3" />
                {t("ui.dev.clients.details.endpoints.read_only", "읽기 전용")}
              </Badge>
            </div>
            <Card className="glass-panel">
              <Table>
                <TableBody>
                  {endpoints.map((endpoint) => (
                    <TableRow
                      key={endpoint.labelKey}
                      className="border-border/70"
                    >
                      <TableCell className="w-1/3">
                        <p className="text-xs font-bold uppercase tracking-[0.12em] text-muted-foreground">
                          {t(endpoint.labelKey, endpoint.labelFallback)}
                        </p>
                      </TableCell>
                      <TableCell className="flex items-center justify-between gap-3">
                        <span className="break-all font-mono text-sm">
                          {endpoint.value}
                        </span>
                        <CopyButton
                          value={endpoint.value}
                          className="h-8 w-8 shrink-0"
                          onCopy={() =>
                            toast(
                              t(
                                "msg.dev.clients.details.copy_endpoint",
                                "{{label}}가 복사되었습니다.",
                                {
                                  label: t(
                                    endpoint.labelKey,
                                    endpoint.labelFallback,
                                  ),
                                },
                              ),
                            )
                          }
                        />
                      </TableCell>
                    </TableRow>
                  ))}
                </TableBody>
              </Table>
            </Card>
          </div>
        </div>

        <div className="space-y-6">
          <div className="space-y-4">
            <h2 className="text-xl font-bold">
              {t("ui.dev.clients.details.redirect.title", "리디렉션 URI 설정")}
            </h2>
            <Card className="glass-panel border-primary/20">
              <CardHeader>
                <CardTitle className="text-lg">
                  {t("ui.dev.clients.details.redirect.label", "Redirect URIs")}
                </CardTitle>
                <CardDescription>
                  {t(
                    "msg.dev.clients.details.redirect.description",
                    "인증 성공 후 사용자를 리다이렉트할 허용된 URL 목록입니다. 콤마(,)로 구분하여 여러 개 입력할 수 있습니다.",
                  )}
                </CardDescription>
              </CardHeader>
              <CardContent className="space-y-4">
                <div className="space-y-2">
                  <Label
                    htmlFor="redirect-uris"
                    className="text-sm font-semibold"
                  >
                    {t(
                      "ui.dev.clients.details.redirect.callback_label",
                      "인증 콜백 URL",
                    )}
                  </Label>
                  <Textarea
                    id="redirect-uris"
                    placeholder={t(
                      "ui.dev.clients.details.redirect.placeholder",
                      "https://your-app.com/callback, http://localhost:3000/auth/callback",
                    )}
                    rows={5}
                    value={redirectUris}
                    onChange={(e) => {
                      redirectUrisHydratedRef.current = true;
                      setRedirectUris(e.target.value);
                    }}
                    className="font-mono text-sm"
                  />
                </div>
                <Button
                  className="w-full gap-2"
                  onClick={() => mutation.mutate()}
                  disabled={mutation.isPending}
                >
                  <Save className="h-4 w-4" />
                  {mutation.isPending
                    ? t("msg.common.saving", "저장 중...")
                    : t(
                        "ui.dev.clients.details.redirect.save",
                        "Redirect URIs 저장",
                      )}
                </Button>
              </CardContent>
            </Card>
          </div>

          <div className="glass-panel p-6 opacity-80">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-3">
                <div className="flex h-12 w-12 items-center justify-center rounded-full bg-primary/15 text-primary">
                  <Shield className="h-6 w-6" />
                </div>
                <div>
                  <p className="text-lg font-semibold">
                    {t("ui.dev.clients.details.security.title", "보안 메모")}
                  </p>
                  <p className="text-sm text-muted-foreground">
                    {t(
                      "msg.dev.clients.details.security.note",
                      "엔드포인트는 읽기 전용으로 유지하고, 비밀키 재발행/복사는 감사 로그와 연계하세요.",
                    )}
                  </p>
                </div>
              </div>
            </div>
            <Separator className="my-4" />
            <p className="text-sm text-muted-foreground">
              {t(
                "msg.dev.clients.details.security.footer",
                "비밀키 재발행 작업에는 관리자 세션 TTL 확인과 레이트리밋, 알림 연동을 권장합니다.",
              )}
            </p>
          </div>
        </div>
      </div>
    </div>
  );
}

export default ClientDetailsPage;
