import { useMemo, useState } from "react";
import {
  ChevronRight,
  Hash,
  Lock,
  Volume2,
  Plus,
  MessageSquare,
  FolderOpen,
  Newspaper,
} from "lucide-react";
import { Link, useLocation, useParams } from "react-router";
import { cn } from "@/lib/utils";

export type Room = {
  id: string;
  name: string;
  topic?: string | null;
  room_type: string;
  is_private: boolean;
  ai_enabled?: boolean;
  category?: string | null;
  workspace_id: string;
};

export type Category = {
  id: string;
  name: string;
  position: number;
};

type Props = {
  rooms: Room[];
  categories?: Category[];
  loading: boolean;
  onCreateChannel?: () => void;
};

function RoomIcon({ type }: { type: string }) {
  if (type === "voice")
    return <Volume2 className="size-[15px] shrink-0 text-muted-foreground/60" />;
  if (type === "article")
    return <Newspaper className="size-[15px] shrink-0 text-muted-foreground/60" />;
  return <Hash className="size-[15px] shrink-0 text-muted-foreground/60" />;
}

function RoomLink({
  room,
  projectName,
}: {
  room: Room;
  projectName: string;
}) {
  const location = useLocation();
  const active = location.pathname.endsWith(`/channel/${room.id}`);

  return (
    <Link
      className={cn(
        "group flex h-9 items-center gap-2 rounded-lg px-2.5 text-[13px] transition-[background-color,color,box-shadow] duration-150",
        active
          ? "bg-primary/[0.08] font-semibold text-foreground ring-1 ring-primary/10"
          : "text-muted-foreground/70 hover:bg-accent/50 hover:text-foreground",
      )}
      to={`/${projectName}/channel/${room.id}`}
    >
      <span
        className={cn(
          "shrink-0 transition-colors duration-150",
          active ? "text-primary/70" : "text-muted-foreground/50 group-hover:text-muted-foreground/70",
        )}
      >
        <RoomIcon type={room.room_type} />
      </span>
      <span className="min-w-0 flex-1 truncate">{room.name}</span>
      {room.is_private && (
        <Lock className="size-3 shrink-0 text-muted-foreground/30" />
      )}
    </Link>
  );
}

function CollapsibleSection({
  title,
  icon,
  defaultOpen = true,
  count,
  children,
}: {
  title: string;
  icon: React.ReactNode;
  defaultOpen?: boolean;
  count?: number;
  children: React.ReactNode;
}) {
  const [open, setOpen] = useState(defaultOpen);

  return (
    <div className="mb-0.5">
      <button
        className="flex w-full cursor-pointer items-center gap-1.5 rounded-md px-1.5 py-[3px] text-[11px] font-semibold uppercase tracking-[0.06em] text-muted-foreground/40 transition-colors hover:text-muted-foreground/70"
        onClick={() => setOpen((v) => !v)}
        type="button"
      >
        <ChevronRight
          className={cn(
            "size-3.5 shrink-0 transition-transform duration-200",
            open && "rotate-90",
          )}
        />
        {icon}
        <span className="flex-1 text-left">{title}</span>
        {count !== undefined && (
          <span className="text-[10px] tabular-nums text-muted-foreground/30">
            {count}
          </span>
        )}
      </button>
      <div
        className={cn(
          "grid transition-[grid-template-rows] duration-200",
          open ? "grid-rows-[1fr]" : "grid-rows-[0fr]",
        )}
      >
        <div className="overflow-hidden">
          <div className="space-y-[1px] py-0.5">{children}</div>
        </div>
      </div>
    </div>
  );
}

function SidebarSkeleton() {
  return (
    <div className="space-y-1 px-3 py-4">
      <div className="mb-4 h-3 w-24 animate-pulse rounded bg-muted/40" />
      {Array.from({ length: 5 }).map((_, i) => (
        <div
          className="h-8 animate-pulse rounded-md bg-muted/30"
          key={i}
          style={{ animationDelay: `${i * 60}ms` }}
        />
      ))}
    </div>
  );
}

export default function ChannelSidebar({
  rooms,
  categories = [],
  loading,
  onCreateChannel,
}: Props) {
  const { projectName = "" } = useParams();

  const { categorized, uncategorized } = useMemo(() => {
    const categorizedGroups: {
      id: string;
      name: string;
      rooms: Room[];
    }[] = [];
    const uncategorizedList: Room[] = [];

    if (categories.length > 0) {
      const catMap = new Map(
        categories.map((c) => [c.id, { id: c.id, name: c.name, rooms: [] as Room[] }]),
      );
      for (const room of rooms) {
        const catId = room.category ?? null;
        const group = catId ? catMap.get(catId) : undefined;
        if (group) {
          group.rooms.push(room);
        } else {
          uncategorizedList.push(room);
        }
      }
      const sorted = categories.toSorted((a, b) => a.position - b.position);
      for (const cat of sorted) {
        const group = catMap.get(cat.id);
        if (group && group.rooms.length > 0) {
          categorizedGroups.push(group);
        }
      }
    } else {
      uncategorizedList.push(...rooms);
    }

    return {
      categorized: categorizedGroups,
      uncategorized: uncategorizedList,
    };
  }, [rooms, categories]);

  if (loading) return <SidebarSkeleton />;

  return (
    <div className="flex h-full flex-col">
      {/* Header */}
      <div className="flex h-11 shrink-0 items-center justify-between border-b border-border/40 px-3">
        <h2 className="truncate text-[11px] font-semibold uppercase tracking-[0.08em] text-muted-foreground/50">
          {projectName}
        </h2>
        {onCreateChannel && (
          <button
            aria-label="Create channel"
            className="inline-flex size-8 items-center justify-center rounded-lg text-muted-foreground/40 transition-[background-color,color] duration-150 hover:bg-accent hover:text-foreground"
            onClick={onCreateChannel}
            type="button"
          >
            <Plus className="size-4" />
          </button>
        )}
      </div>

      {/* Content */}
      <div className="min-h-0 flex-1 overflow-y-auto overscroll-contain px-1.5 py-2">
        {uncategorized.length > 0 && (
          <CollapsibleSection
            defaultOpen={true}
            icon={<Hash className="size-3 text-muted-foreground/40" />}
            title="Channels"
          >
            {uncategorized.map((room) => (
              <RoomLink key={room.id} projectName={projectName} room={room} />
            ))}
          </CollapsibleSection>
        )}

        {categorized.map((group) => (
          <CollapsibleSection
            count={group.rooms.length}
            defaultOpen={true}
            icon={<FolderOpen className="size-3 text-muted-foreground/40" />}
            key={group.id}
            title={group.name}
          >
            {group.rooms.map((room) => (
              <RoomLink key={room.id} projectName={projectName} room={room} />
            ))}
          </CollapsibleSection>
        ))}

        {rooms.length === 0 && (
          <div className="flex flex-col items-center px-4 py-20">
            <div className="grid size-12 place-items-center rounded-2xl bg-muted/30">
              <MessageSquare className="size-5 text-muted-foreground/25" />
            </div>
            <p className="mt-4 text-sm font-medium text-muted-foreground/40">
              No channels yet
            </p>
            {onCreateChannel && (
              <button
                className="mt-3 inline-flex cursor-pointer items-center gap-1.5 rounded-lg px-4 py-2 text-sm font-medium text-primary transition-[background-color,color] duration-150 hover:bg-primary/10"
                onClick={onCreateChannel}
                type="button"
              >
                <Plus className="size-4" />
                Create a channel
              </button>
            )}
          </div>
        )}
      </div>
    </div>
  );
}
