import React, { useRef, useEffect, useMemo } from "react";
import type { ParsedMessage } from "../lib/types";
import { MessageBubble } from "./MessageBubble";
import { RedactedDivider } from "./RedactedDivider";

interface Props {
  messages: ParsedMessage[];
  allMessages: ParsedMessage[];
  redactedUuids: Set<string>;
  loading: boolean;
  searchQuery: string;
  selectedForRedaction: Set<string>;
  onToggleRedactionSelection: (uuid: string) => void;
  autoRedactEnabled: boolean;
  focusedIndex?: number;
}

function MessageSkeleton({ delay = 0 }: { delay?: number }) {
  return (
    <div
      className="rounded-xl border border-border-muted bg-surface-raised p-4 space-y-3"
      style={{ animationDelay: `${delay}ms` }}
    >
      <div className="flex items-center gap-2">
        <div className="skeleton w-2 h-2 rounded-full" />
        <div className="skeleton h-3 w-20" />
      </div>
      <div className="space-y-2">
        <div className="skeleton h-4 w-full" />
        <div className="skeleton h-4 w-5/6" />
        <div className="skeleton h-4 w-3/4" />
      </div>
    </div>
  );
}

export function SessionViewer({
  messages,
  allMessages,
  redactedUuids,
  loading,
  searchQuery,
  selectedForRedaction,
  onToggleRedactionSelection,
  autoRedactEnabled,
  focusedIndex = -1,
}: Props) {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (focusedIndex >= 0 && containerRef.current) {
      const el = containerRef.current.querySelector(
        `[data-msg-index="${focusedIndex}"]`
      );
      if (el) {
        el.scrollIntoView({ behavior: "smooth", block: "nearest" });
      }
    }
  }, [focusedIndex]);

  // Auto-scroll to hash anchor on load
  useEffect(() => {
    const hash = window.location.hash;
    if (hash && hash.startsWith("#msg-") && messages.length > 0) {
      requestAnimationFrame(() => {
        const el = document.getElementById(hash.slice(1));
        if (el) {
          el.scrollIntoView({ behavior: "smooth", block: "center" });
          el.classList.add("search-match-focused", "rounded-xl");
          setTimeout(() => el.classList.remove("search-match-focused"), 3000);
        }
      });
    }
  }, [messages.length]);

  // Build display list with redacted dividers and time gaps.
  // Must be called before any early returns to satisfy Rules of Hooks.
  const displayItems = useMemo(() => {
    if (messages.length === 0) return [];

    const visibleUuids = new Set(messages.map((m) => m.uuid));
    const items: Array<
      | { type: "message"; message: ParsedMessage; messageIndex: number }
      | { type: "redacted_divider"; key: string }
      | { type: "time_gap"; key: string; duration: string }
    > = [];

    let prevWasRedactedGap = false;
    let prevTimestamp: string | undefined;
    let messageIndex = 0;
    for (const msg of allMessages) {
      if (redactedUuids.has(msg.uuid)) {
        prevWasRedactedGap = true;
        continue;
      }
      if (!visibleUuids.has(msg.uuid)) {
        continue;
      }
      if (prevWasRedactedGap) {
        items.push({
          type: "redacted_divider",
          key: `divider-${msg.uuid}`,
        });
        prevWasRedactedGap = false;
      }
      // Insert time gap indicator if > 5 minutes between visible messages
      if (prevTimestamp && msg.timestamp) {
        const currTime = new Date(msg.timestamp).getTime();
        const prevTime = new Date(prevTimestamp).getTime();
        const gap = currTime - prevTime;
        if (!isNaN(gap) && gap > 5 * 60 * 1000) {
          items.push({
            type: "time_gap",
            key: `gap-${msg.uuid}`,
            duration: formatDuration(gap),
          });
        }
      }
      if (msg.timestamp) prevTimestamp = msg.timestamp;
      items.push({ type: "message", message: msg, messageIndex });
      messageIndex++;
    }

    return items;
  }, [messages, allMessages, redactedUuids]);

  if (loading) {
    return (
      <div className="max-w-6xl mx-auto p-6 space-y-4">
        <div className="skeleton h-4 w-24 mb-2" />
        {[...Array(4)].map((_, i) => (
          <MessageSkeleton key={i} delay={i * 100} />
        ))}
      </div>
    );
  }

  if (messages.length === 0 && allMessages.length === 0) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-center max-w-sm animate-fade-in">
          <div
            className="w-14 h-14 rounded-2xl flex items-center justify-center mx-auto mb-4 border border-border-muted"
            style={{ background: "linear-gradient(135deg, var(--color-surface-overlay), var(--color-surface-inset))" }}
          >
            <svg className="w-7 h-7 text-foreground-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M7.5 8.25h9m-9 3H12m-9.75 1.51c0 1.6 1.123 2.994 2.707 3.227 1.129.166 2.27.293 3.423.379.35.026.67.21.865.501L12 21l2.755-4.133a1.14 1.14 0 01.865-.501 48.172 48.172 0 003.423-.379c1.584-.233 2.707-1.626 2.707-3.228V6.741c0-1.602-1.123-2.995-2.707-3.228A48.394 48.394 0 0012 3c-2.392 0-4.744.175-7.043.513C3.373 3.746 2.25 5.14 2.25 6.741v6.018z" />
            </svg>
          </div>
          <p className="text-subheading font-medium text-foreground">Select a session</p>
          <p className="text-body text-foreground-muted mt-1.5">Choose a session from the sidebar to view its messages</p>
        </div>
      </div>
    );
  }

  if (messages.length === 0) {
    return (
      <div className="flex items-center justify-center h-full">
        <div className="text-center max-w-sm animate-fade-in">
          <div
            className="w-14 h-14 rounded-2xl flex items-center justify-center mx-auto mb-4 border border-border-muted"
            style={{ background: "linear-gradient(135deg, var(--color-surface-overlay), var(--color-surface-inset))" }}
          >
            <svg className="w-7 h-7 text-foreground-muted" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
              <path strokeLinecap="round" strokeLinejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 01-.659 1.591l-5.432 5.432a2.25 2.25 0 00-.659 1.591v2.927a2.25 2.25 0 01-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 00-.659-1.591L3.659 7.409A2.25 2.25 0 013 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0112 3z" />
            </svg>
          </div>
          <p className="text-subheading font-medium text-foreground">No matching messages</p>
          <p className="text-body text-foreground-muted mt-1.5">Try adjusting your filters or search query</p>
        </div>
      </div>
    );
  }

  return (
    <div className="max-w-6xl mx-auto px-6 py-5">
      <div className="flex items-center justify-between mb-4">
        <span className="text-caption text-foreground-muted tabular-nums">
          {messages.length} message{messages.length !== 1 ? "s" : ""}
        </span>
      </div>
      <div ref={containerRef} className="space-y-3">
        {displayItems.map((item, idx) => {
          if (item.type === "redacted_divider") {
            return <RedactedDivider key={item.key} />;
          }
          if (item.type === "time_gap") {
            return (
              <div key={item.key} className="flex items-center gap-3 py-2">
                <div className="flex-1 h-px bg-border-muted" />
                <span className="text-caption text-foreground-muted tabular-nums flex-shrink-0">
                  {item.duration} later
                </span>
                <div className="flex-1 h-px bg-border-muted" />
              </div>
            );
          }
          const msg = item.message;
          const lq = searchQuery ? searchQuery.toLowerCase() : "";
          const isMatch =
            searchQuery &&
            (msg.content.toLowerCase().includes(lq) ||
              (msg.toolInput && msg.toolInput.toLowerCase().includes(lq)));
          const isDimmed = searchQuery && !isMatch;
          const isFocused = item.messageIndex === focusedIndex;
          return (
            <div
              key={msg.uuid}
              id={`msg-${msg.uuid}`}
              data-msg-index={item.messageIndex}
              className={`${idx < 20 ? "animate-fade-in" : ""} ${isFocused ? "search-match-focused rounded-xl" : ""}`}
              style={idx < 20 ? { animationDelay: `${idx * 20}ms`, animationFillMode: "backwards" } : undefined}
            >
              <MessageBubble
                message={msg}
                searchQuery={searchQuery}
                dimmed={!!isDimmed}
                selectedForRedaction={selectedForRedaction.has(msg.uuid)}
                onToggleRedactionSelection={() =>
                  onToggleRedactionSelection(msg.uuid)
                }
                autoRedactEnabled={autoRedactEnabled}
              />
            </div>
          );
        })}
      </div>
    </div>
  );
}

function formatDuration(ms: number): string {
  const minutes = Math.floor(ms / 60000);
  if (minutes < 60) return `${minutes}m`;
  const hours = Math.floor(minutes / 60);
  const remainMinutes = minutes % 60;
  if (remainMinutes === 0) return `${hours}h`;
  return `${hours}h ${remainMinutes}m`;
}
