import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { Info, Search, Shield, Sparkles, Upload } from "lucide-react";
import { useEffect, useMemo, 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 { Separator } from "../../components/ui/separator";
import { Textarea } from "../../components/ui/textarea";
import { createClient, fetchClient, updateClient } from "../../lib/devApi";
import type { ClientStatus, ClientType } from "../../lib/devApi";
import { cn } from "../../lib/utils";

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>("confidential");
  const [status, setStatus] = useState<ClientStatus>("active");
  const [redirectUris, setRedirectUris] = useState("");
  const [scopes, setScopes] = useState("openid profile email");

  useEffect(() => {
    if (!data) {
      return;
    }
    setName(data.client.name || data.client.id);
    setClientType(data.client.type);
    setStatus(data.client.status);
    setRedirectUris(data.client.redirectUris.join(", "));
    setScopes(data.client.scopes.join(" "));
    const metadata = data.client.metadata ?? {};
    if (typeof metadata.description === "string") {
      setDescription(metadata.description);
    }
    if (typeof metadata.logo_url === "string") {
      setLogoUrl(metadata.logo_url);
    }
  }, [data]);

  const redirectUriList = useMemo(
    () =>
      redirectUris
        .split(",")
        .map((value) => value.trim())
        .filter(Boolean),
    [redirectUris],
  );
  const scopeList = useMemo(
    () =>
      scopes
        .split(/[,\s]+/)
        .map((value) => value.trim())
        .filter(Boolean),
    [scopes],
  );

  const mutation = useMutation({
    mutationFn: async () => {
      const payload = {
        name,
        type: clientType,
        status,
        redirectUris: redirectUriList,
        scopes: scopeList,
        metadata: {
          description,
          logo_url: logoUrl,
        },
      };
      if (isCreate) {
        return createClient(payload);
      }
      return updateClient(clientId as string, payload);
    },
    onSuccess: (result) => {
      queryClient.invalidateQueries({ queryKey: ["clients"] });
      if (result?.client?.id) {
        navigate(`/clients/${result.client.id}/settings`);
      }
    },
  });

  if (!isCreate && isLoading) {
    return <div className="p-8 text-center">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">
        Error loading client: {errMsg || "unknown error"}
      </div>
    );
  }

  const displayName = isCreate
    ? "새 클라이언트"
    : data?.client?.name || data?.client?.id;
  const createdAt = data?.client?.createdAt;
  const updatedAt = undefined;

  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">
            <div className="flex flex-wrap items-center gap-2 text-sm text-muted-foreground">
              <Link to="/clients" className="text-primary hover:underline">
                Applications
              </Link>
              <span>/</span>
              <span className="text-foreground">{displayName}</span>
            </div>
            <div>
              <p className="text-3xl font-black leading-tight">
                {isCreate ? "Create Client" : "Client Details"}
              </p>
              <p className="text-muted-foreground">
                RP 설정과 메타데이터를 관리합니다.
              </p>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <Badge
              variant={status === "active" ? "success" : "muted"}
              className="px-3 py-1 text-xs uppercase"
            >
              {status === "active" ? "Active" : "Inactive"}
            </Badge>
          </div>
        </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"
              >
                Overview
              </Link>
              <Link
                to={`/clients/${clientId}/consents`}
                className="whitespace-nowrap border-b-2 border-transparent text-muted-foreground hover:text-foreground"
              >
                Consent &amp; Users
              </Link>
              <span className="whitespace-nowrap border-b-2 border-primary pb-1 text-primary">
                Settings
              </span>
            </>
          )}
        </div>
      </header>

      <div className="glass-panel p-6">
        <div className="flex flex-wrap items-center justify-between gap-3 border-b border-border pb-4">
          <div>
            <CardTitle className="text-xl font-bold">
              Application Identity
            </CardTitle>
            <CardDescription>
              앱 이름과 설명, 로고를 설정합니다. 필수 필드는 * 로 표시됩니다.
            </CardDescription>
          </div>
          <div className="flex items-center gap-2">
            <div className="flex h-10 items-center rounded-lg border border-input bg-secondary/50 px-3 text-sm text-muted-foreground">
              <Search className="mr-2 h-4 w-4" />
              Search
            </div>
            <div className="h-10 w-10 overflow-hidden rounded-full border border-border bg-muted/40">
              <img
                className="h-full w-full object-cover"
                alt="앱 로고"
                src="https://lh3.googleusercontent.com/aida-public/AB6AXuBFGWfyQ8ZzHXZmha91pG-09N58hcUap10-bU30aIf_CpfOqm8fPIv6j2v_BVGaJMF2gABxv_hnEXUCBvmjZeFpr-c76uC1QQkgMwsdkc2Im0gqS5X1c8sCWLZudDydZo5m7XW-QW1nRSZHYE5XzTqrW2ITgruSa7eC2Oe9RtxeVFCrqcHw3RO3h0WLtyJ8yhkkeZrAyBc4UQtpcL5bhBDSdlUNgw0odf12Mk6oNojf7Rcg4HPnywh6C-mUtJd-UfX7Y3Yv_W704T1a"
              />
            </div>
          </div>
        </div>

        <div className="grid gap-8 pt-6 md:grid-cols-2">
          <div className="space-y-5">
            <div className="space-y-2">
              <Label className="flex items-center gap-1 text-sm font-semibold">
                앱 이름 <span className="text-destructive">*</span>
              </Label>
              <Input value={name} onChange={(e) => setName(e.target.value)} />
            </div>
            <div className="space-y-2">
              <Label className="text-sm font-semibold">Description</Label>
              <Textarea
                rows={3}
                value={description}
                onChange={(e) => setDescription(e.target.value)}
              />
            </div>
          </div>

          <div className="space-y-2">
            <Label className="text-sm font-semibold">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)}
                />
                <p className="text-xs text-muted-foreground">
                  PNG/SVG URL을 입력하세요.
                </p>
              </div>
              <div className="flex h-20 w-20 items-center justify-center overflow-hidden rounded-lg border-2 border-dashed border-border bg-muted/40">
                <Upload className="h-5 w-5 text-muted-foreground" />
              </div>
            </div>
          </div>
        </div>
      </div>

      <Card className="glass-panel">
        <CardHeader className="pb-3">
          <CardTitle className="text-xl font-bold">보안 설정</CardTitle>
          <CardDescription>
            클라이언트 유형을 선택하세요. 비밀키를 안전하게 보관할 수 없는 경우
            Public을 선택합니다.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <Label className="flex items-center gap-2 text-base font-semibold">
            Client Type
            <Info className="h-4 w-4 text-muted-foreground" />
          </Label>
          <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",
                clientType === "confidential"
                  ? "border-primary bg-primary/5"
                  : "border-border bg-card hover:border-muted-foreground/40",
              )}
            >
              <input
                className="sr-only"
                type="radio"
                name="client-type"
                checked={clientType === "confidential"}
                onChange={() => setClientType("confidential")}
              />
              <span className="flex items-center gap-2 text-sm font-bold uppercase text-foreground">
                <Shield className="h-4 w-4 text-primary" />
                Confidential
              </span>
              <span className="text-sm text-muted-foreground">
                서버 사이드 앱(예: Node.js, Java)처럼 비밀키를 안전하게 보관
                가능.
              </span>
              <span className="absolute right-4 top-4 text-primary">✓</span>
            </label>

            <label
              className={cn(
                "relative flex cursor-pointer flex-col gap-1 rounded-xl border-2 p-4 transition",
                clientType === "public"
                  ? "border-primary bg-primary/5"
                  : "border-border bg-card hover:border-muted-foreground/40",
              )}
            >
              <input
                className="sr-only"
                type="radio"
                name="client-type"
                checked={clientType === "public"}
                onChange={() => setClientType("public")}
              />
              <span className="flex items-center gap-2 text-sm font-bold uppercase text-foreground">
                <Sparkles className="h-4 w-4" />
                Public
              </span>
              <span className="text-sm text-muted-foreground">
                SPA/모바일 앱처럼 비밀키 보관이 어려운 경우. PKCE를 기본
                적용하세요.
              </span>
            </label>
          </div>
        </CardContent>
      </Card>

      <Card className="glass-panel">
        <CardHeader className="pb-3">
          <CardTitle className="text-xl font-bold">
            Redirect URIs & Scopes
          </CardTitle>
          <CardDescription>
            리다이렉트 URI는 콤마로 구분합니다. 스코프는 공백 또는 콤마로 입력할
            수 있습니다.
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-4">
          <div className="space-y-2">
            <Label className="text-sm font-semibold">Redirect URIs *</Label>
            <Input
              value={redirectUris}
              onChange={(e) => setRedirectUris(e.target.value)}
              placeholder="https://app.example.com/callback, https://app.example.com/redirect"
            />
          </div>
          <div className="space-y-2">
            <Label className="text-sm font-semibold">Scopes</Label>
            <Input
              value={scopes}
              onChange={(e) => setScopes(e.target.value)}
              placeholder="openid profile email"
            />
          </div>
        </CardContent>
      </Card>

      <div className="flex items-center justify-end gap-3 border-t border-border pt-4">
        <Button variant="outline" onClick={() => navigate("/clients")}>
          취소
        </Button>
        <Button onClick={() => mutation.mutate()} disabled={mutation.isLoading}>
          {isCreate ? "생성" : "저장"}
        </Button>
      </div>

      {!isCreate && (
        <div className="glass-panel flex flex-wrap gap-x-12 gap-y-4 p-4">
          <div className="space-y-1">
            <span className="text-xs font-semibold uppercase text-muted-foreground">
              Client ID
            </span>
            <span className="font-mono text-sm">{data?.client?.id}</span>
          </div>
          <div className="space-y-1">
            <span className="text-xs font-semibold uppercase text-muted-foreground">
              Created On
            </span>
            <span className="text-sm text-muted-foreground">
              {createdAt ? new Date(createdAt).toLocaleString() : "-"}
            </span>
          </div>
          <div className="space-y-1">
            <span className="text-xs font-semibold uppercase text-muted-foreground">
              Last Updated
            </span>
            <span className="text-sm text-muted-foreground">
              {updatedAt ? new Date(updatedAt).toLocaleString() : "-"}
            </span>
          </div>
        </div>
      )}
    </div>
  );
}

export default ClientGeneralPage;
