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 { AvatarGroup } from '@/components/ui/avatar';
import { HumanAvatar } from '@/components/human-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,
  Lock,
  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>
                    <HumanAvatar
                      size="sm"
                      avatarObjectId={display.avatarObjectId}
                      initials={display.initials}
                      fallbackClassName="bg-red-500/30 text-[8px] text-red-200"
                    />
                  </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 userId = useAuthStore((s) => s.user?.id);
  const humans = network?.humans ?? [];

  const isNetworkWide = visibility.mode === 'network';
  const allMemberIds = isNetworkWide
    ? humans.map((h) => h.id)
    : visibility.humanIds;
  const othersIds = isNetworkWide
    ? []
    : allMemberIds.filter((id) => id != userId);

  const isPrivate = othersIds.length == 0;

  const shownMembers = othersIds
    .slice(0, 3)
    .map((id) => humans.find((h) => h.id === id))
    .filter((h): h is NonNullable<typeof h> => !!h);
  const overflow = othersIds.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"
        >
          {isNetworkWide ? (
            <>
              <Globe className="size-3 text-white/50" />
              <span>Everyone</span>
            </>
          ) : isPrivate ? (
            <>
              <Lock className="size-3 text-white/50" />
              <span>Private</span>
            </>
          ) : (
            <>
              <AvatarGroup>
                {shownMembers.map((human) => (
                  <HumanAvatar
                    key={human.id}
                    size="sm"
                    avatarObjectId={human.avatar_object_id}
                    initials={resolveHumanDisplay(human.id, humans).initials}
                    fallbackClassName="text-[8px]"
                  />
                ))}
              </AvatarGroup>
              {overflow > 0 && (
                <span className="text-white/50">+{overflow}</span>
              )}
            </>
          )}
        </button>
      </TooltipTrigger>
      <TooltipContent>
        {isNetworkWide
          ? `Everyone in ${network?.name ?? 'network'}`
          : `${allMemberIds.length} ${allMemberIds.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">
      <HumanAvatar
        size="sm"
        className={isOnline ? 'ring-2 ring-green-500' : ''}
        avatarObjectId={display.avatarObjectId}
        initials={display.initials}
      />
      {display.displayName} - <RelativeTimestamp date={particle.created_at} />
    </span>
  );
}
