import { useState, useEffect, useMemo } from "react";
import { cn } from "@/lib/utils";
import { trpc } from "@/lib/trpc";
import {
  Plus,
  MessageSquare,
  Settings,
  Trash2,
  Edit3,
  Check,
  X,
  ChevronLeft,
  ChevronRight,
  DollarSign,
  Zap,
  LogOut,
  Search,
  ChevronDown,
} from "lucide-react";
import { useAuth } from "@/_core/hooks/useAuth";
import { getLoginUrl } from "@/const";

interface SidebarProps {
  currentSessionId: number | null;
  onSelectSession: (id: number) => void;
  onNewSession: () => void;
  onOpenSettings: () => void;
  collapsed: boolean;
  onToggleCollapse: () => void;
}

type DateGroup = "Today" | "Yesterday" | "This Week" | "This Month" | "Older";

function getDateGroup(dateStr: string): DateGroup {
  const date = new Date(dateStr);
  const now = new Date();
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
  const yesterday = new Date(today);
  yesterday.setDate(yesterday.getDate() - 1);
  const weekAgo = new Date(today);
  weekAgo.setDate(weekAgo.getDate() - 7);
  const monthAgo = new Date(today);
  monthAgo.setMonth(monthAgo.getMonth() - 1);

  if (date >= today) return "Today";
  if (date >= yesterday) return "Yesterday";
  if (date >= weekAgo) return "This Week";
  if (date >= monthAgo) return "This Month";
  return "Older";
}

const GROUP_ORDER: DateGroup[] = ["Today", "Yesterday", "This Week", "This Month", "Older"];

export function Sidebar({
  currentSessionId,
  onSelectSession,
  onNewSession,
  onOpenSettings,
  collapsed,
  onToggleCollapse,
}: SidebarProps) {
  const { user } = useAuth();
  const utils = trpc.useUtils();
  const { data: sessions, isLoading } = trpc.sessions.list.useQuery();
  const { data: costSummary } = trpc.costs.summary.useQuery(undefined, {
    enabled: !!user,
  });
  const deleteMutation = trpc.sessions.delete.useMutation({
    onSuccess: () => utils.sessions.list.invalidate(),
  });
  const updateMutation = trpc.sessions.update.useMutation({
    onSuccess: () => utils.sessions.list.invalidate(),
  });
  const logoutMutation = trpc.auth.logout.useMutation({
    onSuccess: () => window.location.reload(),
  });

  const [editingId, setEditingId] = useState<number | null>(null);
  const [editTitle, setEditTitle] = useState("");
  const [searchQuery, setSearchQuery] = useState("");
  const [collapsedGroups, setCollapsedGroups] = useState<Set<DateGroup>>(new Set());

  // Filter sessions by search
  const filteredSessions = useMemo(() => {
    if (!sessions) return [];
    if (!searchQuery.trim()) return sessions;
    const q = searchQuery.toLowerCase();
    return sessions.filter(
      (s) =>
        s.title.toLowerCase().includes(q) ||
        (s.model && s.model.toLowerCase().includes(q))
    );
  }, [sessions, searchQuery]);

  // Group sessions by date
  const groupedSessions = useMemo(() => {
    const groups = new Map<DateGroup, typeof filteredSessions>();
    for (const session of filteredSessions) {
      const group = getDateGroup(session.updatedAt || session.createdAt);
      if (!groups.has(group)) groups.set(group, []);
      groups.get(group)!.push(session);
    }
    return groups;
  }, [filteredSessions]);

  const toggleGroup = (group: DateGroup) => {
    setCollapsedGroups((prev) => {
      const next = new Set(prev);
      if (next.has(group)) next.delete(group);
      else next.add(group);
      return next;
    });
  };

  // Listen for title updates from SSE
  useEffect(() => {
    const handler = () => {
      utils.sessions.list.invalidate();
    };
    window.addEventListener("session-title-update", handler);
    return () => window.removeEventListener("session-title-update", handler);
  }, [utils]);

  const startEdit = (id: number, title: string) => {
    setEditingId(id);
    setEditTitle(title);
  };

  const saveEdit = () => {
    if (editingId && editTitle.trim()) {
      updateMutation.mutate({ id: editingId, title: editTitle.trim() });
    }
    setEditingId(null);
  };

  if (collapsed) {
    return (
      <div className="w-12 bg-sidebar border-r border-sidebar-border flex flex-col items-center py-3 gap-2">
        <button
          onClick={onToggleCollapse}
          className="size-8 rounded-lg hover:bg-sidebar-accent flex items-center justify-center text-sidebar-foreground/60 hover:text-sidebar-foreground transition-colors"
        >
          <ChevronRight className="size-4" />
        </button>
        <button
          onClick={onNewSession}
          className="size-8 rounded-lg bg-primary/20 hover:bg-primary/30 flex items-center justify-center text-primary transition-colors"
          title="New session"
        >
          <Plus className="size-4" />
        </button>
        <div className="flex-1" />
        <button
          onClick={onOpenSettings}
          className="size-8 rounded-lg hover:bg-sidebar-accent flex items-center justify-center text-sidebar-foreground/60 hover:text-sidebar-foreground transition-colors"
          title="Settings"
        >
          <Settings className="size-4" />
        </button>
      </div>
    );
  }

  const renderSession = (session: (typeof filteredSessions)[0]) => (
    <div
      key={session.id}
      className={cn(
        "group flex items-center gap-2 rounded-lg px-2.5 py-2 cursor-pointer transition-colors",
        session.id === currentSessionId
          ? "bg-sidebar-accent text-sidebar-accent-foreground"
          : "text-sidebar-foreground/70 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground"
      )}
      onClick={() => onSelectSession(session.id)}
    >
      <MessageSquare className="size-3.5 shrink-0 opacity-60" />

      {editingId === session.id ? (
        <div className="flex-1 flex items-center gap-1">
          <input
            value={editTitle}
            onChange={(e) => setEditTitle(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === "Enter") saveEdit();
              if (e.key === "Escape") setEditingId(null);
            }}
            className="flex-1 bg-background text-xs rounded px-1.5 py-0.5 outline-none border border-border"
            autoFocus
            onClick={(e) => e.stopPropagation()}
          />
          <button
            onClick={(e) => {
              e.stopPropagation();
              saveEdit();
            }}
            className="text-green-400 hover:text-green-300"
          >
            <Check className="size-3" />
          </button>
          <button
            onClick={(e) => {
              e.stopPropagation();
              setEditingId(null);
            }}
            className="text-muted-foreground hover:text-foreground"
          >
            <X className="size-3" />
          </button>
        </div>
      ) : (
        <>
          <span className="flex-1 text-xs truncate">{session.title}</span>
          <div className="hidden group-hover:flex items-center gap-0.5">
            <button
              onClick={(e) => {
                e.stopPropagation();
                startEdit(session.id, session.title);
              }}
              className="size-5 rounded hover:bg-background/50 flex items-center justify-center"
            >
              <Edit3 className="size-3" />
            </button>
            <button
              onClick={(e) => {
                e.stopPropagation();
                if (confirm("Delete this session?")) {
                  deleteMutation.mutate({ id: session.id });
                }
              }}
              className="size-5 rounded hover:bg-destructive/20 text-destructive flex items-center justify-center"
            >
              <Trash2 className="size-3" />
            </button>
          </div>
        </>
      )}
    </div>
  );

  return (
    <div className="w-64 bg-sidebar border-r border-sidebar-border flex flex-col h-full">
      {/* Header */}
      <div className="p-3 flex items-center justify-between border-b border-sidebar-border">
        <div className="flex items-center gap-2">
          <Zap className="size-5 text-primary" />
          <span className="font-semibold text-sm text-sidebar-foreground">
            Claw
          </span>
        </div>
        <div className="flex items-center gap-1">
          <button
            onClick={onNewSession}
            className="size-7 rounded-md hover:bg-sidebar-accent flex items-center justify-center text-sidebar-foreground/60 hover:text-sidebar-foreground transition-colors"
            title="New session"
          >
            <Plus className="size-4" />
          </button>
          <button
            onClick={onToggleCollapse}
            className="size-7 rounded-md hover:bg-sidebar-accent flex items-center justify-center text-sidebar-foreground/60 hover:text-sidebar-foreground transition-colors"
          >
            <ChevronLeft className="size-4" />
          </button>
        </div>
      </div>

      {/* Search */}
      <div className="px-2 pt-2">
        <div className="relative">
          <Search className="absolute left-2 top-1/2 -translate-y-1/2 size-3.5 text-muted-foreground" />
          <input
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder="Search sessions..."
            className="w-full bg-sidebar-accent/50 border border-sidebar-border rounded-md pl-7 pr-2 py-1.5 text-xs outline-none focus:border-primary placeholder:text-muted-foreground/50"
          />
        </div>
      </div>

      {/* Sessions list — grouped by date */}
      <div className="flex-1 overflow-y-auto py-2 px-2">
        {isLoading && (
          <div className="text-xs text-muted-foreground text-center py-4">
            Loading sessions...
          </div>
        )}
        {filteredSessions.length === 0 && !isLoading && (
          <div className="text-xs text-muted-foreground text-center py-4">
            {searchQuery ? "No matching sessions" : "No sessions yet"}
          </div>
        )}
        {GROUP_ORDER.map((group) => {
          const groupSessions = groupedSessions.get(group);
          if (!groupSessions || groupSessions.length === 0) return null;
          const isCollapsed = collapsedGroups.has(group);
          return (
            <div key={group} className="mb-2">
              <button
                onClick={() => toggleGroup(group)}
                className="w-full flex items-center gap-1.5 px-1 py-1 text-[10px] font-semibold uppercase tracking-wider text-muted-foreground/60 hover:text-muted-foreground transition-colors"
              >
                <ChevronDown
                  className={cn(
                    "size-3 transition-transform",
                    isCollapsed && "-rotate-90"
                  )}
                />
                <span>{group}</span>
                <span className="ml-auto text-[9px] font-normal opacity-50">
                  {groupSessions.length}
                </span>
              </button>
              {!isCollapsed && (
                <div className="space-y-0.5">
                  {groupSessions.map(renderSession)}
                </div>
              )}
            </div>
          );
        })}
      </div>

      {/* Cost widget */}
      {costSummary && (
        <div className="mx-2 mb-2 px-2.5 py-2 rounded-lg bg-sidebar-accent/30 border border-sidebar-border">
          <div className="flex items-center gap-1.5 text-[10px] text-muted-foreground mb-0.5">
            <DollarSign className="size-3" />
            <span>Total Cost</span>
          </div>
          <div className="text-sm font-mono font-semibold text-primary">
            ${Number(costSummary.totalCost || 0).toFixed(4)}
          </div>
          <div className="text-[10px] text-muted-foreground">
            {Number(costSummary.totalPromptTokens || 0).toLocaleString()} +{" "}
            {Number(costSummary.totalCompletionTokens || 0).toLocaleString()}{" "}
            tokens
          </div>
        </div>
      )}

      {/* Bottom section */}
      <div className="border-t border-sidebar-border p-2 space-y-0.5">
        <button
          onClick={onOpenSettings}
          className="w-full flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-sidebar-foreground/70 hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors"
        >
          <Settings className="size-3.5" />
          <span className="text-xs">Settings</span>
        </button>

        {user ? (
          <div className="flex items-center gap-2 px-2.5 py-2">
            <div className="size-6 rounded-full bg-primary/20 flex items-center justify-center text-primary text-[10px] font-bold">
              {user.name?.[0]?.toUpperCase() || "U"}
            </div>
            <span className="flex-1 text-xs text-sidebar-foreground/70 truncate">
              {user.name || "User"}
            </span>
            <button
              onClick={() => logoutMutation.mutate()}
              className="size-6 rounded hover:bg-sidebar-accent flex items-center justify-center text-sidebar-foreground/40 hover:text-sidebar-foreground transition-colors"
              title="Logout"
            >
              <LogOut className="size-3" />
            </button>
          </div>
        ) : (
          <a
            href={getLoginUrl()}
            className="w-full flex items-center gap-2.5 rounded-lg px-2.5 py-2 text-primary hover:bg-sidebar-accent/50 transition-colors"
          >
            <span className="text-xs font-medium">Sign in</span>
          </a>
        )}
      </div>
    </div>
  );
}
