import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
  CheckCircle2,
  ClipboardCheck,
  Clock,
  Plus,
  ShieldAlert,
  X,
  XCircle,
} from "lucide-react";
import { useEffect, useState } from "react";
import { useAuth } from "react-oidc-context";
import { PageHeader } from "../../../../common/core/components/page";
import {
  commonStickyTableHeaderClass,
  commonTableShellClass,
  commonTableViewportClass,
} from "../../../../common/ui/table";
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 { Textarea } from "../../components/ui/textarea";
import {
  approveDeveloperRequest,
  cancelDeveloperRequestApproval,
  fetchDeveloperRequests,
  fetchMyTenants,
  rejectDeveloperRequest,
  requestDeveloperAccess,
} from "../../lib/devApi";
import { t } from "../../lib/i18n";
import { resolveProfileRole } from "../../lib/role";
import { fetchMe } from "../auth/authApi";
import {
  type DeveloperAccessPage,
  developerAccessPageOptions,
  normalizeDeveloperAccessPageSelection,
  normalizeDeveloperAccessPages,
} from "../developer-access/developerAccessPages";

export default function DeveloperRequestPage() {
  const auth = useAuth();
  const queryClient = useQueryClient();
  const hasAccessToken = Boolean(auth.user?.access_token);
  const userProfile = auth.user?.profile as Record<string, unknown> | undefined;
  const role = resolveProfileRole(userProfile);
  const tenantId = userProfile?.tenant_id as string | undefined;
  const companyCode = userProfile?.companyCode as string | undefined;

  const [isRequestModalOpen, setIsRequestModalOpen] = useState(false);
  const [adminNotes, setAdminNotes] = useState<Record<number, string>>({});

  const { data: requests, isLoading } = useQuery({
    queryKey: ["developer-requests"],
    queryFn: () => fetchDeveloperRequests(),
    enabled: !!auth.user?.access_token,
  });
  const { data: tenants } = useQuery({
    queryKey: ["myTenants"],
    queryFn: fetchMyTenants,
    enabled: !!auth.user?.access_token,
  });
  const { data: me } = useQuery({
    queryKey: ["userMe"],
    queryFn: fetchMe,
    enabled: hasAccessToken,
  });

  const currentTenant = tenants?.find(
    (tenant) => tenant.id === tenantId || tenant.slug === companyCode,
  );
  const organizationName = currentTenant?.name || companyCode || "";
  const profileName = me?.name || (userProfile?.name as string) || "";
  const profileEmail = me?.email || (userProfile?.email as string) || "";
  const profilePhone =
    me?.phone ||
    (userProfile?.phone as string | undefined) ||
    (userProfile?.phone_number as string | undefined) ||
    "";
  const profileRole = me?.role?.trim() || role;
  const isSuperAdmin = profileRole === "super_admin";
  const profileRoleLabel = t(`ui.admin.role.${profileRole}`, profileRole);

  const approveMutation = useMutation({
    mutationFn: ({ id, adminNotes }: { id: number; adminNotes: string }) =>
      approveDeveloperRequest(id, adminNotes),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["developer-requests"] });
      alert(t("msg.dev.request.approved", "승인되었습니다."));
    },
  });

  const rejectMutation = useMutation({
    mutationFn: ({ id, adminNotes }: { id: number; adminNotes: string }) =>
      rejectDeveloperRequest(id, adminNotes),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["developer-requests"] });
      alert(t("msg.dev.request.rejected", "반려되었습니다."));
    },
  });

  const cancelApprovalMutation = useMutation({
    mutationFn: ({ id, adminNotes }: { id: number; adminNotes: string }) =>
      cancelDeveloperRequestApproval(id, adminNotes),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["developer-requests"] });
      queryClient.invalidateQueries({ queryKey: ["developer-request"] });
      alert(t("msg.dev.request.cancelled", "승인이 취소되었습니다."));
    },
  });

  const handleApprove = (id: number) => {
    approveMutation.mutate({ id, adminNotes: adminNotes[id] || "" });
  };

  const handleReject = (id: number) => {
    if (!adminNotes[id]) {
      alert(t("msg.dev.request.need_notes", "반려 사유를 입력해주세요."));
      return;
    }
    rejectMutation.mutate({ id, adminNotes: adminNotes[id] });
  };

  const handleCancelApproval = (id: number) => {
    if (!adminNotes[id]) {
      alert(
        t(
          "msg.dev.request.need_cancel_notes",
          "승인 취소 사유를 입력해주세요.",
        ),
      );
      return;
    }
    cancelApprovalMutation.mutate({ id, adminNotes: adminNotes[id] });
  };

  if (isLoading) {
    return (
      <div className="p-8 text-center">
        {t("ui.common.loading", "Loading...")}
      </div>
    );
  }

  const hasActiveRequest = requests?.some((r) => r.status === "pending");
  const approvedRequestCount =
    requests?.filter((request) => request.status === "approved").length ?? 0;
  const isActionPending =
    approveMutation.isPending ||
    rejectMutation.isPending ||
    cancelApprovalMutation.isPending;

  return (
    <div className="space-y-6">
      <PageHeader
        icon={<ClipboardCheck size={20} />}
        title={t("ui.dev.nav.developer_request", "개발자 권한 신청")}
        description={
          isSuperAdmin
            ? t(
                "msg.dev.request.admin_desc",
                "사용자들의 개발자 권한 신청 내역을 관리합니다.",
              )
            : t(
                "msg.dev.request.user_desc",
                "내 신청 내역을 확인하고 새로운 권한을 신청할 수 있습니다.",
              )
        }
        actions={
          !isSuperAdmin && !hasActiveRequest ? (
            <Button onClick={() => setIsRequestModalOpen(true)}>
              <Plus className="mr-2 h-4 w-4" />
              {t("ui.dev.welcome.btn_request", "신규 신청하기")}
            </Button>
          ) : null
        }
      />

      <Card className="glass-panel">
        <CardHeader>
          <CardTitle className="text-xl">
            {t("ui.dev.request.list.title", "신청 내역")}
          </CardTitle>
          <CardDescription>
            {t(
              "msg.dev.request.list.approved_count",
              "총 {{count}}명의 사용자가 승인되었습니다.",
              { count: approvedRequestCount },
            )}
          </CardDescription>
        </CardHeader>
        <CardContent>
          <div className={commonTableShellClass}>
            <div className={commonTableViewportClass}>
              <Table>
                <TableHeader className={commonStickyTableHeaderClass}>
                  <TableRow>
                    {isSuperAdmin && (
                      <TableHead>
                        {t("ui.dev.request.table.user", "사용자")}
                      </TableHead>
                    )}
                    <TableHead>
                      {t("ui.dev.request.table.org", "소속")}
                    </TableHead>
                    <TableHead>
                      {t("ui.dev.request.table.reason", "신청 사유")}
                    </TableHead>
                    <TableHead>
                      {t("ui.dev.request.table.pages", "권한 페이지")}
                    </TableHead>
                    <TableHead>
                      {t("ui.dev.request.table.status", "상태")}
                    </TableHead>
                    <TableHead>
                      {t("ui.dev.request.table.date", "신청일")}
                    </TableHead>
                    {isSuperAdmin && (
                      <TableHead className="text-right">
                        {t("ui.dev.request.table.actions", "관리")}
                      </TableHead>
                    )}
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {!requests || requests.length === 0 ? (
                    <TableRow>
                      <TableCell
                        colSpan={isSuperAdmin ? 7 : 5}
                        className="h-32 text-center text-muted-foreground"
                      >
                        {t("msg.dev.request.empty", "신청 내역이 없습니다.")}
                      </TableCell>
                    </TableRow>
                  ) : (
                    requests.map((req) => (
                      <TableRow key={req.id}>
                        {isSuperAdmin && (
                          <TableCell className="font-medium">
                            <div>{req.name}</div>
                            <div className="text-xs text-muted-foreground">
                              {req.email || req.userId}
                            </div>
                            {(req.phone || req.role) && (
                              <div className="mt-1 text-xs text-muted-foreground">
                                {[req.phone, req.role]
                                  .filter(Boolean)
                                  .join(" / ")}
                              </div>
                            )}
                          </TableCell>
                        )}
                        <TableCell>
                          {req.organization?.trim() ||
                            t("ui.common.na", "없음")}
                        </TableCell>
                        <TableCell className="max-w-md">
                          <div className="truncate" title={req.reason}>
                            {req.reason}
                          </div>
                          {req.adminNotes && (
                            <div className="mt-1 rounded bg-amber-50 p-1.5 text-xs text-amber-600 dark:bg-amber-900/20">
                              <strong>Admin:</strong> {req.adminNotes}
                            </div>
                          )}
                        </TableCell>
                        <TableCell>
                          <div className="flex flex-wrap gap-1">
                            {req.accessPages?.length ? (
                              normalizeDeveloperAccessPages(
                                req.accessPages,
                              ).map((page) => (
                                <Badge key={page} variant="outline">
                                  {developerAccessPageOptions.find(
                                    (option) => option.value === page,
                                  )?.label ?? page}
                                </Badge>
                              ))
                            ) : (
                              <Badge variant="secondary">
                                {t("ui.common.na", "없음")}
                              </Badge>
                            )}
                          </div>
                        </TableCell>
                        <TableCell>
                          <StatusBadge status={req.status} />
                        </TableCell>
                        <TableCell className="text-sm text-muted-foreground">
                          {new Date(req.createdAt).toLocaleDateString()}
                        </TableCell>
                        {isSuperAdmin && (
                          <TableCell className="text-right">
                            {req.status === "pending" ? (
                              <div className="ml-auto flex min-w-[200px] flex-col items-end gap-2">
                                <Input
                                  placeholder={t(
                                    "ui.dev.request.admin_notes_placeholder",
                                    "메모 입력 (선택)...",
                                  )}
                                  className="h-8 text-xs"
                                  value={adminNotes[req.id] || ""}
                                  onChange={(e) =>
                                    setAdminNotes({
                                      ...adminNotes,
                                      [req.id]: e.target.value,
                                    })
                                  }
                                />
                                <div className="flex gap-2">
                                  <Button
                                    size="sm"
                                    variant="outline"
                                    className="text-destructive hover:bg-destructive/10"
                                    onClick={() => handleReject(req.id)}
                                    disabled={isActionPending}
                                  >
                                    <XCircle className="mr-1 h-3 w-3" />
                                    {t("ui.common.reject", "반려")}
                                  </Button>
                                  <Button
                                    size="sm"
                                    className="bg-emerald-600 hover:bg-emerald-700"
                                    onClick={() => handleApprove(req.id)}
                                    disabled={isActionPending}
                                  >
                                    <CheckCircle2 className="mr-1 h-3 w-3" />
                                    {t("ui.common.approve", "승인")}
                                  </Button>
                                </div>
                              </div>
                            ) : req.status === "approved" ? (
                              <div className="ml-auto flex min-w-[200px] flex-col items-end gap-2">
                                <Input
                                  placeholder={t(
                                    "ui.dev.request.cancel_notes_placeholder",
                                    "승인 취소 사유 입력...",
                                  )}
                                  className="h-8 text-xs"
                                  value={adminNotes[req.id] || ""}
                                  onChange={(e) =>
                                    setAdminNotes({
                                      ...adminNotes,
                                      [req.id]: e.target.value,
                                    })
                                  }
                                />
                                <Button
                                  size="sm"
                                  variant="outline"
                                  className="text-destructive hover:bg-destructive/10"
                                  onClick={() => handleCancelApproval(req.id)}
                                  disabled={isActionPending}
                                >
                                  <XCircle className="mr-1 h-3 w-3" />
                                  {t(
                                    "ui.dev.request.cancel_approval",
                                    "승인 취소",
                                  )}
                                </Button>
                              </div>
                            ) : (
                              <span className="text-xs italic text-muted-foreground">
                                {req.status === "cancelled"
                                  ? t(
                                      "ui.dev.request.status.cancelled",
                                      "승인 취소됨",
                                    )
                                  : t("ui.common.rejected", "반려됨")}
                              </span>
                            )}
                          </TableCell>
                        )}
                      </TableRow>
                    ))
                  )}
                </TableBody>
              </Table>
            </div>
          </div>
        </CardContent>
      </Card>

      <RequestAccessModal
        isOpen={isRequestModalOpen}
        onClose={() => setIsRequestModalOpen(false)}
        onSuccess={() => {
          queryClient.invalidateQueries({ queryKey: ["developer-requests"] });
          setIsRequestModalOpen(false);
        }}
        tenantId={tenantId || ""}
        initialName={profileName}
        initialOrg={organizationName}
        initialEmail={profileEmail}
        initialPhone={profilePhone}
        initialRole={profileRoleLabel}
      />
    </div>
  );
}

function StatusBadge({ status }: { status: string }) {
  switch (status) {
    case "pending":
      return (
        <Badge variant="warning" className="gap-1">
          <Clock className="h-3 w-3" />
          {t("ui.dev.request.status.pending", "대기 중")}
        </Badge>
      );
    case "approved":
      return (
        <Badge variant="success" className="gap-1">
          <CheckCircle2 className="h-3 w-3" />
          {t("ui.dev.request.status.approved", "승인됨")}
        </Badge>
      );
    case "rejected":
      return (
        <Badge variant="muted" className="gap-1">
          <ShieldAlert className="h-3 w-3" />
          {t("ui.dev.request.status.rejected", "반려됨")}
        </Badge>
      );
    case "cancelled":
      return (
        <Badge variant="muted" className="gap-1">
          <XCircle className="h-3 w-3" />
          {t("ui.dev.request.status.cancelled", "승인 취소됨")}
        </Badge>
      );
    default:
      return <Badge variant="muted">{status}</Badge>;
  }
}

interface RequestAccessModalProps {
  isOpen: boolean;
  onClose: () => void;
  onSuccess: () => void;
  tenantId: string;
  initialName: string;
  initialOrg: string;
  initialEmail: string;
  initialPhone: string;
  initialRole: string;
}

function RequestAccessModal({
  isOpen,
  onClose,
  onSuccess,
  tenantId,
  initialName,
  initialOrg,
  initialEmail,
  initialPhone,
  initialRole,
}: RequestAccessModalProps) {
  const [name, setName] = useState(initialName);
  const [organization, setOrganization] = useState(initialOrg);
  const [reason, setReason] = useState("");
  const [accessPages, setAccessPages] = useState<DeveloperAccessPage[]>([
    "all",
  ]);
  const organizationDisplay = organization.trim() || t("ui.common.na", "없음");

  useEffect(() => {
    if (!isOpen) return;
    setName(initialName);
    setOrganization(initialOrg);
    setAccessPages(["all"]);
  }, [initialName, initialOrg, isOpen]);

  const mutation = useMutation({
    mutationFn: requestDeveloperAccess,
    onSuccess: () => {
      onSuccess();
    },
  });

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    mutation.mutate({
      name,
      organization,
      reason,
      tenantId,
      accessPages: normalizeDeveloperAccessPageSelection(accessPages),
    });
  };

  const handleAccessPageToggle = (page: DeveloperAccessPage) => {
    setAccessPages((current) => {
      if (page === "all") {
        return ["all"];
      }
      const withoutAll = current.filter((item) => item !== "all");
      if (withoutAll.includes(page)) {
        const next = withoutAll.filter((item) => item !== page);
        return next.length > 0 ? next : ["all"];
      }
      return normalizeDeveloperAccessPageSelection([...withoutAll, page]);
    });
  };

  if (!isOpen) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-background/80 backdrop-blur-sm animate-in fade-in duration-200">
      <div className="relative w-full max-w-lg bg-card border border-border shadow-2xl rounded-2xl overflow-hidden animate-in zoom-in-95 duration-200">
        <div className="flex items-center justify-between p-6 border-b border-border/40">
          <div>
            <h2 className="text-xl font-bold tracking-tight">
              {t("ui.dev.request.modal.title", "개발자 등록 신청")}
            </h2>
            <p className="text-sm text-muted-foreground mt-1">
              {t(
                "msg.dev.request.modal.desc",
                "신청 사유를 입력해 주세요. 관리자 확인 후 승인됩니다.",
              )}
            </p>
          </div>
          <Button
            variant="ghost"
            size="icon"
            className="rounded-full"
            onClick={onClose}
          >
            <X className="h-4 w-4" />
          </Button>
        </div>

        <form onSubmit={handleSubmit} className="p-6 space-y-6">
          <div className="grid gap-4">
            <div className="grid gap-2">
              <Label htmlFor="name">
                {t("ui.dev.request.modal.name", "성함")}
              </Label>
              <Input
                id="name"
                value={name}
                readOnly
                className="focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-input"
                required
              />
            </div>
            <div className="grid gap-2">
              <Label htmlFor="org">
                {t("ui.dev.request.modal.org", "소속")}
              </Label>
              <Input
                id="org"
                value={organizationDisplay}
                readOnly
                className="focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-input"
                required
              />
            </div>
            <div className="grid gap-4 md:grid-cols-2">
              <div className="grid gap-2">
                <Label htmlFor="email">
                  {t("ui.dev.request.modal.email", "이메일")}
                </Label>
                <Input
                  id="email"
                  value={initialEmail}
                  readOnly
                  className="focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-input"
                />
              </div>
              <div className="grid gap-2">
                <Label htmlFor="phone">
                  {t("ui.dev.request.modal.phone", "전화번호")}
                </Label>
                <Input
                  id="phone"
                  value={initialPhone}
                  readOnly
                  className="focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-input"
                />
              </div>
            </div>
            <div className="grid gap-2">
              <Label htmlFor="role">
                {t("ui.dev.request.modal.role", "역할")}
              </Label>
              <Input
                id="role"
                value={initialRole}
                readOnly
                className="focus-visible:ring-0 focus-visible:ring-offset-0 focus-visible:border-input"
              />
            </div>
            <div className="grid gap-3">
              <Label>
                {t("ui.dev.request.modal.pages", "권한 페이지")}{" "}
                <span className="text-destructive">*</span>
              </Label>
              <div className="grid gap-2 rounded-lg border border-border/60 bg-muted/20 p-3">
                {developerAccessPageOptions.map((option) => {
                  const checked =
                    option.value === "all"
                      ? accessPages.includes("all")
                      : accessPages.includes(option.value);
                  return (
                    <label
                      key={option.value}
                      className="flex items-center gap-3 rounded-md px-2 py-1.5 text-sm hover:bg-background/60"
                    >
                      <input
                        type="checkbox"
                        checked={checked}
                        onChange={() => handleAccessPageToggle(option.value)}
                      />
                      <span className="font-medium">{option.label}</span>
                    </label>
                  );
                })}
              </div>
              <p className="text-xs text-muted-foreground">
                {t(
                  "msg.dev.request.modal.pages_hint",
                  "전체를 선택하면 개요, 연동 앱 추가, 감사로그가 모두 포함됩니다.",
                )}
              </p>
            </div>
            <div className="grid gap-2">
              <Label htmlFor="reason">
                {t("ui.dev.request.modal.reason", "신청 사유")}{" "}
                <span className="text-destructive">*</span>
              </Label>
              <Textarea
                id="reason"
                value={reason}
                onChange={(e) => setReason(e.target.value)}
                placeholder={t(
                  "ui.dev.request.modal.reason_placeholder",
                  "예: 자체 서비스 연동 및 테스트용 OIDC 클라이언트 생성이 필요합니다.",
                )}
                className="min-h-[120px] resize-none border-primary/50 bg-background focus-visible:ring-primary/40"
                required
              />
            </div>
          </div>

          <div className="flex items-center justify-end gap-3 pt-2">
            <Button type="button" variant="outline" onClick={onClose}>
              {t("ui.common.cancel", "취소")}
            </Button>
            <Button
              type="submit"
              disabled={mutation.isPending}
              className="px-8 font-bold"
            >
              {mutation.isPending
                ? t("ui.common.submitting", "제출 중...")
                : t("ui.common.submit", "신청하기")}
            </Button>
          </div>
        </form>
      </div>
    </div>
  );
}
