import { useState } from "react";
import { useNavigate } from "react-router-dom";
import { useAuthStore } from "@/stores/auth-store";
import { apiClient } from "@/api/client";
import { isParticleDeleted, type Particle } from "@/api/types";
import { particlePath, toFirestoreDocPath } from "@/lib/particle-path";
import { Avatar, AvatarFallback, AvatarGroup } from "@/components/ui/avatar";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { useNetwork } from "@/hooks/use-networks";
import { Button } from "@/components/ui/button";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Settings, CircleCheckBig, CircleDot, EllipsisVertical, Pencil, Globe, Trash2 } from "lucide-react";
import { updateStreamStatus } from "@/lib/firestore-particles";
import { RenameStreamOverlay } from "@/features/particles/rename-stream-overlay";
import { DeleteParticleOverlay } from "@/features/particles/delete-particle-overlay";
import { StreamMembersOverlay } from "@/features/particles/stream-members-overlay";
import { parseVisibleTo } from "@/lib/stream-visibility";
import { Breadcrumb, BreadcrumbItem, BreadcrumbList, BreadcrumbPage, BreadcrumbSeparator } from "@/components/ui/breadcrumb";
import { WindowControls } from "@/components/window-controls";
import { RelativeTimestamp } from "@/components/relative-timestamp";
import { useStreamPresence } from "@/features/particles/stream-presence-context";
import { resolveHumanDisplay } from "@/lib/humans";
import { platform } from "@/lib/platform";
import { requireDesktop } from "@/lib/platform/desktop-only";

function getParticleDisplayName(particle: Particle): string {
  switch (particle.type) {
    case "stream":
    case "folder":
      return particle.properties.name;
    case "quest":
      return particle.properties.title;
    case "paper":
      return particle.properties.title;
    case "file":
      return particle.properties.filename;
    case "text":
      return particle.properties.content.slice(0, 30);
    case "media":
      return particle.type;
  }
}

interface TopBarProps {
  networkId: string;
  particle: Particle | null;
  streamParticle: Particle & { type: "stream" };
}

export function TopBar({ networkId, particle, streamParticle }: TopBarProps) {
  const navigate = useNavigate();
  const network = useNetwork(networkId);
  const userId = useAuthStore((s) => s.user?.id);
  const isCreator = !!userId && userId === streamParticle.created_by_human_id;
  const [renameOpen, setRenameOpen] = useState(false);
  const [membersOpen, setMembersOpen] = useState(false);
  const [deleteOpen, setDeleteOpen] = useState(false);

  const canDeleteParticle =
    !!particle &&
    !!userId &&
    particle.created_by_human_id === userId &&
    particle.type !== "stream" &&
    particle.type !== "folder" &&
    !isParticleDeleted(particle);

  const huddleParticipants = streamParticle.huddle_active_participants ?? [];
  const hasActiveHuddle = huddleParticipants.length > 0;

  const handleJoinHuddle = () => {
    if (!requireDesktop("Huddle")) return;
    apiClient.getLivekitToken(networkId, streamParticle.id).then(({ token, server_url }) => {
      platform.huddle.open({ token, serverUrl: server_url });
    });
  };

  return (
    <div className="drag-region flex flex-row px-2 gap-1 items-center">
      <WindowControls />

      <Breadcrumb className="no-drag rounded-full bg-black/30 backdrop-blur-sm px-3 py-1 mx-auto">
        <BreadcrumbList>
          {streamParticle && (
            <>
              <BreadcrumbItem className="text-xs">
                <BreadcrumbPage>{getParticleDisplayName(streamParticle)}</BreadcrumbPage>
              </BreadcrumbItem>
            </>
          )}

          {particle && (
            <>
              <BreadcrumbSeparator />
              <BreadcrumbItem className="text-xs">
                <BreadcrumbPage><ParticleBreadcrumbContent particle={particle} networkId={networkId} /></BreadcrumbPage>
              </BreadcrumbItem>
            </>
          )}
        </BreadcrumbList>
      </Breadcrumb>

      {hasActiveHuddle && (
        <button
          onClick={handleJoinHuddle}
          className="no-drag flex items-center gap-2 rounded-full bg-red-500/20 px-3 py-1 backdrop-blur-sm transition-colors hover:bg-red-500/30"
        >
          <span className="relative flex size-2">
            <span className="absolute inline-flex size-full animate-ping rounded-full bg-red-400 opacity-75" />
            <span className="relative inline-flex size-2 rounded-full bg-red-500" />
          </span>
          <AvatarGroup>
            {huddleParticipants.map((humanId) => {
              const display = resolveHumanDisplay(humanId, network?.humans);
              return (
                <Tooltip key={humanId}>
                  <TooltipTrigger asChild>
                    <Avatar size="sm">
                      <AvatarFallback className="bg-red-500/30 text-[8px] text-red-200">
                        {display.initials}
                      </AvatarFallback>
                    </Avatar>
                  </TooltipTrigger>
                  <TooltipContent>{display.email}</TooltipContent>
                </Tooltip>
              );
            })}
          </AvatarGroup>
          <span className="text-xs font-medium text-red-200">Join</span>
        </button>
      )}

      {streamParticle.status === "closed" && (
        <span className="no-drag flex items-center gap-1 rounded-full bg-white/10 px-2 py-0.5 text-xs text-muted-foreground backdrop-blur-sm">
          <CircleCheckBig className="size-3" />
          Closed
        </span>
      )}

      <MembersIndicator
        networkId={networkId}
        streamParticle={streamParticle}
        onClick={() => setMembersOpen(true)}
      />

      <DropdownMenu>
        <DropdownMenuTrigger asChild>
          <Button
            variant="ghost"
            size="sm"
            className="no-drag text-muted-foreground"
          >
            <EllipsisVertical className="size-3.5" />
          </Button>
        </DropdownMenuTrigger>
        <DropdownMenuContent align="end">
          <DropdownMenuItem
            onSelect={async () => {
              const docPath = toFirestoreDocPath(particlePath(networkId, [streamParticle.id]));
              await updateStreamStatus(docPath, streamParticle.status === "open" ? "closed" : "open");
            }}
          >
            {streamParticle.status === "open" ? (
              <>
                <CircleCheckBig className="size-4" />
                Close stream
              </>
            ) : (
              <>
                <CircleDot className="size-4 text-green-500" />
                Open stream
              </>
            )}
          </DropdownMenuItem>
          {isCreator && (
            <DropdownMenuItem onSelect={() => setRenameOpen(true)}>
              <Pencil className="size-4" />
              Rename stream
            </DropdownMenuItem>
          )}
          {canDeleteParticle && (
            <DropdownMenuItem
              onSelect={() => setDeleteOpen(true)}
              variant="destructive"
            >
              <Trash2 className="size-4" />
              Delete particle
            </DropdownMenuItem>
          )}
          <DropdownMenuItem onSelect={() => navigate("/settings")}>
            <Settings className="size-4" />
            Settings
          </DropdownMenuItem>
        </DropdownMenuContent>
      </DropdownMenu>

      {renameOpen && isCreator && (
        <RenameStreamOverlay
          networkId={networkId}
          streamParticle={streamParticle}
          onClose={() => setRenameOpen(false)}
        />
      )}

      {deleteOpen && canDeleteParticle && particle && userId && (
        <DeleteParticleOverlay
          networkId={networkId}
          streamId={streamParticle.id}
          particle={particle}
          userId={userId}
          onClose={() => setDeleteOpen(false)}
        />
      )}

      {membersOpen && (
        <StreamMembersOverlay
          networkId={networkId}
          streamParticle={streamParticle}
          isCreator={isCreator}
          onClose={() => setMembersOpen(false)}
        />
      )}
    </div>
  );
}

function MembersIndicator({
  networkId,
  streamParticle,
  onClick,
}: {
  networkId: string;
  streamParticle: Particle & { type: "stream" };
  onClick: () => void;
}) {
  const network = useNetwork(networkId);
  const visibility = parseVisibleTo(streamParticle.visible_to, networkId);
  const humans = network?.humans ?? [];

  const memberIds =
    visibility.mode === "network"
      ? humans.map((h) => h.id)
      : visibility.humanIds;
  const shownMembers = memberIds
    .slice(0, 3)
    .map((id) => humans.find((h) => h.id === id))
    .filter((h): h is NonNullable<typeof h> => !!h);
  const overflow = memberIds.length - shownMembers.length;

  return (
    <Tooltip>
      <TooltipTrigger asChild>
        <button
          onClick={onClick}
          className="no-drag flex items-center gap-1.5 rounded-full bg-white/5 px-2 py-1 text-xs text-white/70 backdrop-blur-sm transition-colors hover:bg-white/10"
        >
          {visibility.mode === "network" ? (
            <>
              <Globe className="size-3 text-white/50" />
              <span>Everyone</span>
            </>
          ) : (
            <>
              <AvatarGroup>
                {shownMembers.map((human) => (
                  <Avatar key={human.id} size="sm">
                    <AvatarFallback className="text-[8px]">
                      {resolveHumanDisplay(human.id, humans).initials}
                    </AvatarFallback>
                  </Avatar>
                ))}
              </AvatarGroup>
              {overflow > 0 && <span className="text-white/50">+{overflow}</span>}
            </>
          )}
        </button>
      </TooltipTrigger>
      <TooltipContent>
        {visibility.mode === "network"
          ? `Everyone in ${network?.name ?? "network"}`
          : `${memberIds.length} ${memberIds.length === 1 ? "member" : "members"}`}
      </TooltipContent>
    </Tooltip>
  );
}

function ParticleBreadcrumbContent({ particle, networkId }: { particle: Particle; networkId: string }) {
  const network = useNetwork(networkId);
  const { onlineHumanIds } = useStreamPresence();
  const display = resolveHumanDisplay(particle.created_by_human_id, network?.humans);
  const isOnline = particle.created_by_human_id ? onlineHumanIds.has(particle.created_by_human_id) : false;

  return (
    <span className="flex items-center gap-1.5">
      <Avatar size="sm" className={isOnline ? "ring-2 ring-green-500" : ""}>
        <AvatarFallback>
          {display.initials}
        </AvatarFallback>
      </Avatar>
      {display.displayName} - <RelativeTimestamp date={particle.created_at} />
    </span>
  );
}
