import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import type { AxiosError } from "axios";
import { ArrowLeft, Link2, Plus, Trash2 } from "lucide-react";
import { useMemo, useState } from "react";
import { Link, 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 {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "../../components/ui/table";
import { toast } from "../../components/ui/use-toast";
import {
  addClientRelation,
  fetchClient,
  fetchClientRelations,
  removeClientRelation,
} from "../../lib/devApi";
import { t } from "../../lib/i18n";

const relationOptions = [
  "admins",
  "creator",
  "config_editor",
  "secret_rotator",
  "jwks_viewer",
  "jwks_operator",
  "consent_viewer",
  "consent_revoker",
  "relationship_viewer",
  "status_operator",
] as const;

function ClientRelationsPage() {
  const params = useParams();
  const queryClient = useQueryClient();
  const clientId = params.id ?? "";
  const [relation, setRelation] = useState<(typeof relationOptions)[number]>(
    "config_editor",
  );
  const [userId, setUserId] = useState("");

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

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

  const sortedItems = useMemo(() => {
    return [...(relationData?.items ?? [])].sort((a, b) => {
      const relationCompare = a.relation.localeCompare(b.relation);
      if (relationCompare !== 0) {
        return relationCompare;
      }
      return a.subject.localeCompare(b.subject);
    });
  }, [relationData?.items]);

  const addMutation = useMutation({
    mutationFn: () =>
      addClientRelation(clientId, {
        relation,
        userId: userId.trim(),
      }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["client-relations", clientId] });
      setUserId("");
      toast(
        t(
          "msg.dev.clients.relationships.added",
          "Relationship가 추가되었습니다.",
        ),
      );
    },
    onError: (err) => {
      toast(
        t(
          "msg.dev.clients.relationships.add_error",
          "Relationship 추가 실패: {{error}}",
          {
            error:
              (err as AxiosError<{ error?: string }>).response?.data?.error ??
              (err as Error).message,
          },
        ),
        "error",
      );
    },
  });

  const removeMutation = useMutation({
    mutationFn: (payload: { relation: string; subject: string }) =>
      removeClientRelation(clientId, payload.relation, payload.subject),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["client-relations", clientId] });
      toast(
        t(
          "msg.dev.clients.relationships.removed",
          "Relationship가 제거되었습니다.",
        ),
      );
    },
    onError: (err) => {
      toast(
        t(
          "msg.dev.clients.relationships.remove_error",
          "Relationship 제거 실패: {{error}}",
          {
            error:
              (err as AxiosError<{ error?: string }>).response?.data?.error ??
              (err as Error).message,
          },
        ),
        "error",
      );
    },
  });

  const handleAdd = () => {
    if (!userId.trim()) {
      toast(
        t(
          "msg.dev.clients.relationships.user_required",
          "추가할 User ID를 입력하세요.",
        ),
        "error",
      );
      return;
    }
    addMutation.mutate();
  };

  const handleRemove = (targetRelation: string, subject: string) => {
    if (
      window.confirm(
        t(
          "msg.dev.clients.relationships.remove_confirm",
          "이 relationship를 제거하시겠습니까?",
        ),
      )
    ) {
      removeMutation.mutate({ relation: targetRelation, subject });
    }
  };

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

  return (
    <div className="space-y-8">
      <header className="space-y-4">
        <div className="flex flex-wrap 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>{clientData?.client?.name || clientId}</span>
              <span>/</span>
              <span className="text-foreground font-semibold">
                {t(
                  "ui.dev.clients.details.tab.relationships",
                  "Relationships",
                )}
              </span>
            </nav>
            <div className="flex items-center gap-2">
              <Button variant="ghost" size="icon" asChild>
                <Link to={`/clients/${clientId}`}>
                  <ArrowLeft className="h-4 w-4" />
                </Link>
              </Button>
              <div>
                <p className="text-3xl font-black leading-tight">
                  {t(
                    "ui.dev.clients.relationships.title",
                    "Client Relationships",
                  )}
                </p>
                <p className="text-muted-foreground">
                  {t(
                    "msg.dev.clients.relationships.subtitle",
                    "RP direct operator relation을 조회하고 User 단위로 추가·삭제합니다.",
                  )}
                </p>
              </div>
            </div>
          </div>
          <div className="flex items-center gap-3">
            <Badge
              variant={
                clientData?.client?.status === "active" ? "info" : "muted"
              }
            >
              {clientData?.client?.status === "active"
                ? t("ui.common.status.active", "Active")
                : t("ui.common.status.inactive", "Inactive")}
            </Badge>
          </div>
        </div>
        <div className="flex gap-6 overflow-x-auto border-b border-border pb-3 text-sm font-bold">
          <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>
          <Link
            to={`/clients/${clientId}/settings`}
            className="whitespace-nowrap border-b-2 border-transparent text-muted-foreground hover:text-foreground"
          >
            {t("ui.dev.clients.details.tab.settings", "Settings")}
          </Link>
          <span className="whitespace-nowrap border-b-2 border-primary pb-1 text-primary">
            {t("ui.dev.clients.details.tab.relationships", "Relationships")}
          </span>
        </div>
      </header>

      <Card className="glass-panel">
        <CardHeader>
          <CardTitle>
            {t("ui.dev.clients.relationships.add_title", "Add Relationship")}
          </CardTitle>
          <CardDescription>
            {t(
              "msg.dev.clients.relationships.add_description",
              "현재는 direct User assignment만 지원합니다. subject는 자동으로 User:<id> 형식으로 전송됩니다.",
            )}
          </CardDescription>
        </CardHeader>
        <CardContent className="grid gap-4 md:grid-cols-[220px_minmax(0,1fr)_auto] md:items-end">
          <div className="space-y-2">
            <Label htmlFor="relation-select">
              {t("ui.dev.clients.relationships.relation", "Relation")}
            </Label>
            <select
              id="relation-select"
              value={relation}
              onChange={(e) =>
                setRelation(e.target.value as (typeof relationOptions)[number])
              }
              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
            >
              {relationOptions.map((option) => (
                <option key={option} value={option}>
                  {option}
                </option>
              ))}
            </select>
          </div>
          <div className="space-y-2">
            <Label htmlFor="user-id-input">
              {t("ui.dev.clients.relationships.user_id", "User ID")}
            </Label>
            <Input
              id="user-id-input"
              value={userId}
              onChange={(e) => setUserId(e.target.value)}
              placeholder={t(
                "ui.dev.clients.relationships.user_id_placeholder",
                "kratos user id",
              )}
            />
          </div>
          <Button
            onClick={handleAdd}
            disabled={addMutation.isPending}
            className="gap-2"
          >
            <Plus className="h-4 w-4" />
            {addMutation.isPending
              ? t("msg.common.loading", "Loading...")
              : t("ui.dev.clients.relationships.add", "Add")}
          </Button>
        </CardContent>
      </Card>

      <Card className="glass-panel">
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <Link2 className="h-5 w-5" />
            {t(
              "ui.dev.clients.relationships.list_title",
              "Assigned Relationships",
            )}
          </CardTitle>
          <CardDescription>
            {t(
              "msg.dev.clients.relationships.list_description",
              "현재 RP에 직접 부여된 operator relation 목록입니다.",
            )}
          </CardDescription>
        </CardHeader>
        <CardContent>
          {error ? (
            <div className="rounded-md border border-destructive/30 bg-destructive/5 p-4 text-sm text-destructive">
              {t(
                "msg.dev.clients.relationships.load_error",
                "Relationship 조회 실패: {{error}}",
                {
                  error:
                    (error as AxiosError<{ error?: string }>).response?.data
                      ?.error ?? (error as Error).message,
                },
              )}
            </div>
          ) : isLoading ? (
            <div className="py-8 text-center text-sm text-muted-foreground">
              {t(
                "msg.dev.clients.relationships.loading",
                "Relationship를 불러오는 중입니다...",
              )}
            </div>
          ) : sortedItems.length === 0 ? (
            <div className="py-8 text-center text-sm text-muted-foreground">
              {t(
                "msg.dev.clients.relationships.empty",
                "직접 부여된 relationship가 없습니다.",
              )}
            </div>
          ) : (
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead>
                    {t("ui.dev.clients.relationships.relation", "Relation")}
                  </TableHead>
                  <TableHead>
                    {t("ui.dev.clients.relationships.subject", "Subject")}
                  </TableHead>
                  <TableHead>
                    {t("ui.dev.clients.relationships.subject_type", "Type")}
                  </TableHead>
                  <TableHead className="w-[120px] text-right">
                    {t("ui.dev.clients.table.actions", "액션")}
                  </TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {sortedItems.map((item) => (
                  <TableRow key={`${item.relation}:${item.subject}`}>
                    <TableCell className="font-mono text-xs">
                      {item.relation}
                    </TableCell>
                    <TableCell>
                      <div className="space-y-1">
                        <div className="font-mono text-xs">{item.subject}</div>
                        {item.subjectId && (
                          <div className="text-xs text-muted-foreground">
                            ID: {item.subjectId}
                          </div>
                        )}
                      </div>
                    </TableCell>
                    <TableCell>
                      <Badge variant="outline">{item.subjectType || "-"}</Badge>
                    </TableCell>
                    <TableCell className="text-right">
                      <Button
                        variant="ghost"
                        size="sm"
                        className="gap-2 text-destructive hover:text-destructive"
                        disabled={removeMutation.isPending}
                        onClick={() =>
                          handleRemove(item.relation, item.subject)
                        }
                      >
                        <Trash2 className="h-4 w-4" />
                        {t("ui.common.delete", "Delete")}
                      </Button>
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      </Card>
    </div>
  );
}

export default ClientRelationsPage;
