"use client";

import { useEffect, useState } from "react";

import AppShell from "@/components/AppShell";
import Avatar from "@/components/ui/avatar";
import { Check, Copy, Eye, Users } from "lucide-react";

import {
  AlertDialog,
  AlertDialogAction,
  AlertDialogCancel,
  AlertDialogContent,
  AlertDialogDescription,
  AlertDialogFooter,
  AlertDialogHeader,
  AlertDialogTitle,
  AlertDialogTrigger,
} from "@/components/ui/alert-dialog";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { api } from "@/lib/api";
import { useTranslation } from "@/lib/i18n";

type RegisteredUser = {
  id: string;
  username: string;
  avatar?: string | null;
  createdAt: string;
};

type Invite = {
  id: string;
  code: string;
  creator_id: string;
  max_uses: number;
  used_count: number;
  expires_at: string;
  revoked_at: string | null;
  created_at: string;
};

type InviteWithUsers = {
  id: string;
  code: string;
  creatorId: string;
  maxUses: number;
  usedCount: number;
  expiresAt: string;
  revokedAt: string | null;
  createdAt: string;
  registeredUsers: RegisteredUser[];
};

const InvitesPage = () => {
  const t = useTranslation();
  const [invites, setInvites] = useState<Invite[]>([]);
  const [maxUses, setMaxUses] = useState(5);
  const [expiresInDays, setExpiresInDays] = useState(7);
  const [selectedInvite, setSelectedInvite] = useState<InviteWithUsers | null>(null);
  const [detailsOpen, setDetailsOpen] = useState(false);
  const [copiedId, setCopiedId] = useState<string | null>(null);

  const load = async () => {
    const data = await api.getInvites();
    setInvites(data as Invite[]);
  };

  useEffect(() => {
    load().catch(() => null);
  }, []);

  const createInvite = async (event: React.FormEvent) => {
    event.preventDefault();
    await api.createInvite({ maxUses, expiresInDays });
    setMaxUses(5);
    setExpiresInDays(7);
    await load();
  };

  const revokeInvite = async (id: string) => {
    await api.revokeInvite(id);
    await load();
  };

  const viewDetails = async (id: string) => {
    const data = await api.getInvite(id);
    setSelectedInvite(data as InviteWithUsers);
    setDetailsOpen(true);
  };

  const copyCode = async (code: string, id: string) => {
    await navigator.clipboard.writeText(code);
    setCopiedId(id);
    setTimeout(() => setCopiedId(null), 2000);
  };

  const formatDateTime = (dateStr: string): string => {
    const d = new Date(dateStr);
    const pad = (n: number) => n.toString().padStart(2, "0");
    return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`;
  };

  const getInviteStatus = (invite: Invite): { key: string; color: string } => {
    if (invite.revoked_at) {
      return { key: "statusRevoked", color: "bg-red-100 text-red-700" };
    }
    if (new Date(invite.expires_at) < new Date()) {
      return { key: "statusExpired", color: "bg-muted text-muted-foreground" };
    }
    if (invite.used_count >= invite.max_uses) {
      return { key: "statusExhausted", color: "bg-amber-100 text-amber-700" };
    }
    return { key: "statusActive", color: "bg-green-100 text-green-700" };
  };

  return (
    <AppShell>
      <div>
        <h1 className="text-xl font-semibold tracking-tight text-foreground">{t("navInvites")}</h1>
        <p className="mt-1 text-sm text-muted-foreground">{t("createInviteDesc")}</p>
      </div>
      <div className="grid gap-6 lg:grid-cols-2">
        <Card>
          <CardHeader>
            <CardTitle>{t("createInvite")}</CardTitle>
            <CardDescription>{t("createInviteDesc")}</CardDescription>
          </CardHeader>
          <CardContent>
            <form className="space-y-4" onSubmit={createInvite}>
              <div className="space-y-2">
                <Label htmlFor="maxUses">{t("maxUses")}</Label>
                <Input
                  id="maxUses"
                  type="number"
                  min={1}
                  max={20}
                  value={maxUses}
                  onChange={(event) => setMaxUses(Number(event.target.value))}
                />
              </div>
              <div className="space-y-2">
                <Label htmlFor="expiresInDays">{t("expiresInDays")}</Label>
                <Input
                  id="expiresInDays"
                  type="number"
                  min={1}
                  max={30}
                  value={expiresInDays}
                  onChange={(event) => setExpiresInDays(Number(event.target.value))}
                />
              </div>
              <Button type="submit">{t("generateInvite")}</Button>
            </form>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>{t("myInvites")}</CardTitle>
            <CardDescription>{t("myInvitesDesc")}</CardDescription>
          </CardHeader>
          <CardContent>
            <div className="grid gap-3">
              {invites.map((invite) => {
                const status = getInviteStatus(invite);
                const isActive = status.key === "statusActive";
                return (
                  <div
                    key={invite.id}
                    className="flex items-center justify-between rounded-lg bg-muted/50 px-4 py-3 transition-colors hover:bg-muted"
                  >
                    <div className="min-w-0 flex-1">
                      <div className="flex items-center gap-2">
                        <code className="rounded bg-muted px-2 py-0.5 text-sm font-semibold text-foreground">
                          {invite.code}
                        </code>
                        <button
                          type="button"
                          onClick={() => copyCode(invite.code, invite.id)}
                          className="rounded-md p-1 text-muted-foreground hover:bg-muted hover:text-foreground/80"
                          title={t("copyCode")}
                        >
                          {copiedId === invite.id ? (
                            <Check className="h-4 w-4 text-green-500" />
                          ) : (
                            <Copy className="h-4 w-4" />
                          )}
                        </button>
                        <span className={`rounded-full px-2 py-0.5 text-xs font-medium ${status.color}`}>
                          {t(status.key as keyof ReturnType<typeof useTranslation>)}
                        </span>
                      </div>
                      <div className="mt-1 flex items-center gap-3 text-xs text-muted-foreground">
                        <span className="flex items-center gap-1">
                          <Users className="h-3 w-3" />
                          {invite.used_count}/{invite.max_uses}
                        </span>
                        <span>{t("expiresAt")}: {formatDateTime(invite.expires_at)}</span>
                      </div>
                    </div>
                    <div className="flex items-center gap-1">
                      <Button
                        variant="ghost"
                        size="sm"
                        onClick={() => viewDetails(invite.id)}
                        className="text-muted-foreground hover:text-blue-500"
                      >
                        <Eye className="h-4 w-4" />
                      </Button>
                      {isActive && (
                        <AlertDialog>
                          <AlertDialogTrigger asChild>
                            <Button
                              variant="ghost"
                              size="sm"
                              className="text-muted-foreground hover:text-red-500"
                            >
                              {t("revoke")}
                            </Button>
                          </AlertDialogTrigger>
                          <AlertDialogContent>
                            <AlertDialogHeader>
                              <AlertDialogTitle>{t("revokeInvite")}</AlertDialogTitle>
                              <AlertDialogDescription>
                                {t("revokeInviteDesc", { code: invite.code })}
                              </AlertDialogDescription>
                            </AlertDialogHeader>
                            <AlertDialogFooter>
                              <AlertDialogCancel>{t("cancel")}</AlertDialogCancel>
                              <AlertDialogAction
                                className="bg-red-500 hover:bg-red-600"
                                onClick={() => revokeInvite(invite.id)}
                              >
                                {t("revoke")}
                              </AlertDialogAction>
                            </AlertDialogFooter>
                          </AlertDialogContent>
                        </AlertDialog>
                      )}
                    </div>
                  </div>
                );
              })}
              {invites.length === 0 && (
                <div className="rounded-lg bg-muted/50 p-6 text-center text-sm text-muted-foreground">
                  {t("noInvites")}
                </div>
              )}
            </div>
          </CardContent>
        </Card>
      </div>

      {/* Details Dialog */}
      <Dialog open={detailsOpen} onOpenChange={setDetailsOpen}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle className="flex items-center gap-2">
              <code className="rounded bg-muted px-2 py-0.5 text-base">
                {selectedInvite?.code}
              </code>
            </DialogTitle>
            <DialogDescription>
              {t("registeredUsers")}
            </DialogDescription>
          </DialogHeader>
          <div className="space-y-3">
            {selectedInvite?.registeredUsers && selectedInvite.registeredUsers.length > 0 ? (
              selectedInvite.registeredUsers.map((user) => (
                <div
                  key={user.id}
                  className="flex items-center gap-3 rounded-lg bg-muted/50 p-3"
                >
                  <Avatar username={user.username} src={user.avatar} size="sm" />
                  <div className="min-w-0 flex-1">
                    <div className="font-medium text-foreground">{user.username}</div>
                    <div className="text-xs text-muted-foreground">
                      {formatDateTime(user.createdAt)}
                    </div>
                  </div>
                </div>
              ))
            ) : (
              <div className="rounded-lg bg-muted/50 p-6 text-center text-sm text-muted-foreground">
                {t("noRegisteredUsers")}
              </div>
            )}
          </div>
        </DialogContent>
      </Dialog>
    </AppShell>
  );
};

export default InvitesPage;
