"use client";

import { useEffect, useMemo, useState } from "react";
import type { WikiNavigationNode, WikiPageSummary } from "@optage/sdk/client";
import type { WikiProgressStatus } from "@/hooks/useWikiProgress";

interface WikiTreeProps {
  navigation: WikiNavigationNode;
  pages: WikiPageSummary[];
  selectedPageId: string | null;
  onSelectPage: (pageId: string) => void;
  onAction?: () => void;
  onRegenerate?: () => void;
  actionLabel?: "Generate" | "Resume" | "Cancel";
  isGenerating?: boolean;
  isCancelled?: boolean;
  wikiStatus?: WikiProgressStatus | null;
}

function formatEta(etaMs?: number): string | null {
  if (etaMs == null || etaMs <= 0) return null;
  const secs = Math.ceil(etaMs / 1000);
  if (secs < 60) return `~${secs}s left`;
  const mins = Math.floor(secs / 60);
  const rem = secs % 60;
  return `~${mins}m ${rem}s left`;
}

function phaseLabel(phase?: string): string {
  switch (phase) {
    case "scanning": return "Scanning";
    case "building-tree": return "Building tree";
    case "planning": return "Planning";
    case "leaf-docs": return "Generating pages";
    case "parent-docs": return "Parent docs";
    case "overview": return "Writing overview";
    case "guides": return "Creating guides";
    case "dd-docs": return "Detailed designs";
    default: return "Preparing";
  }
}

export function WikiTree({
  navigation: _navigation,
  pages,
  selectedPageId,
  onSelectPage,
  onAction,
  onRegenerate,
  actionLabel,
  isGenerating,
  isCancelled,
  wikiStatus,
}: WikiTreeProps) {
  const allDone =
    wikiStatus?.state === "done" ||
    !wikiStatus ||
    (wikiStatus.state === "idle" && !wikiStatus.completedPageIds);
  const completedPageIds = useMemo(
    () => new Set(wikiStatus?.completedPageIds ?? []),
    [wikiStatus?.completedPageIds],
  );

  const [query, setQuery] = useState("");
  const [debouncedQuery, setDebouncedQuery] = useState("");

  useEffect(() => {
    const timer = setTimeout(() => setDebouncedQuery(query.trim().toLowerCase()), 200);
    return () => clearTimeout(timer);
  }, [query]);

  const normalizedQuery = debouncedQuery;
  const isSearching = normalizedQuery.length > 0;

  const overviewPage = useMemo(
    () => pages.find((page) => page.pageType === "overview") || null,
    [pages],
  );

  const topDomainPages = useMemo(
    () =>
      pages
        .filter((page) => page.pageType === "module" && page.kind !== "integration")
        .filter((page) => getPathDepth(page.path) <= 2)
        .sort(sortPages),
    [pages],
  );

  const workflowPages = useMemo(
    () =>
      pages
        .filter((page) => page.pageType === "workflow")
        .sort(sortPages)
        .slice(0, 8),
    [pages],
  );

  const ddPages = useMemo(
    () =>
      pages
        .filter((page) => page.pageType === "dd")
        .sort(sortPages),
    [pages],
  );

  const integrationPages = useMemo(
    () =>
      pages
        .filter((page) => page.pageType === "module" && page.kind === "integration")
        .sort(sortPages)
        .slice(0, 8),
    [pages],
  );

  const searchResults = useMemo(
    () =>
      pages
        .filter((page) => page.pageType !== "overview")
        .filter((page) => matchesQuery(page, normalizedQuery))
        .sort(sortPages)
        .slice(0, 24),
    [pages, normalizedQuery],
  );

  return (
    <aside className="h-full border-r border-rp-border/10 bg-rp-bg overflow-hidden">
      <div className="flex h-full flex-col">
        <div className="px-3 pt-3 pb-2 shrink-0">
          <input
            type="text"
            value={query}
            onChange={(event) => setQuery(event.target.value)}
            placeholder="Search pages"
            disabled={isGenerating}
            className="w-full rounded-lg px-3 py-1.5 text-r-sm outline-none bg-rp-hover/50 border border-rp-border/40 text-rp-text placeholder:text-rp-faint focus:border-rp-accent/30 disabled:opacity-40"
          />
        </div>

        <div className={`flex-1 min-h-0 px-2 py-3 overflow-y-auto`}>
          {!isSearching ? (
            <>
              {overviewPage ? (
                <NavSection title="Start Here">
                  <NavItem
                    page={overviewPage}
                    selected={selectedPageId === overviewPage.id}
                    onClick={() => onSelectPage(overviewPage.id)}
                    subtitle="Repository Overview"
                    compact
                    generating={!!isGenerating}
                    completed={allDone || completedPageIds.has(overviewPage.id)}
                  />
                </NavSection>
              ) : null}

              <NavSection title="Domains">
                {topDomainPages.length > 0 ? (
                  topDomainPages.map((page) => (
                    <NavItem
                      key={page.id}
                      page={page}
                      selected={selectedPageId === page.id}
                      onClick={() => onSelectPage(page.id)}
                      generating={!!isGenerating}
                      completed={allDone || completedPageIds.has(page.id)}
                    />
                  ))
                ) : (
                  <EmptyState message="No domain pages available." />
                )}
              </NavSection>

              {integrationPages.length > 0 ? (
                <NavSection title="Integrations">
                  {integrationPages.map((page) => (
                    <NavItem
                      key={page.id}
                      page={page}
                      selected={selectedPageId === page.id}
                      onClick={() => onSelectPage(page.id)}
                      compact
                      generating={!!isGenerating}
                      completed={allDone || completedPageIds.has(page.id)}
                    />
                  ))}
                </NavSection>
              ) : null}

              {workflowPages.length > 0 ? (
                <NavSection title="Workflows">
                  {workflowPages.map((page) => (
                    <NavItem
                      key={page.id}
                      page={page}
                      selected={selectedPageId === page.id}
                      onClick={() => onSelectPage(page.id)}
                      compact
                      generating={!!isGenerating}
                      completed={allDone || completedPageIds.has(page.id)}
                    />
                  ))}
                </NavSection>
              ) : null}

              {ddPages.length > 0 ? (
                <NavSection title="Detailed Design">
                  {ddPages.map((page) => (
                    <NavItem
                      key={page.id}
                      page={page}
                      selected={selectedPageId === page.id}
                      onClick={() => onSelectPage(page.id)}
                      compact
                      generating={!!isGenerating}
                      completed={allDone || completedPageIds.has(page.id)}
                    />
                  ))}
                </NavSection>
              ) : null}
            </>
          ) : (
            <NavSection title="Search Results">
              {searchResults.length > 0 ? (
                searchResults.map((page) => (
                  <NavItem
                    key={page.id}
                    page={page}
                    selected={selectedPageId === page.id}
                    onClick={() => onSelectPage(page.id)}
                    subtitle={page.path}
                  />
                ))
              ) : (
                <EmptyState message="No pages match this search." />
              )}
            </NavSection>
          )}
        </div>

        {/* Bottom action button */}
        {onAction && (
          <div className="shrink-0 border-t border-rp-border/10">
            {isGenerating && wikiStatus ? (
              <div className="px-3 pt-2.5 pb-2">
                <div className="flex items-center gap-2 mb-1.5">
                  <div className="w-3 h-3 rounded-full border-[1.5px] border-transparent border-t-rp-accent animate-spin shrink-0" />
                  <span className="text-r-2xs text-rp-muted truncate">
                    {phaseLabel(wikiStatus.phase)}
                    {wikiStatus.message ? ` — ${wikiStatus.message}` : ""}
                  </span>
                </div>
                {typeof wikiStatus.completedSteps === "number" &&
                  typeof wikiStatus.totalSteps === "number" &&
                  wikiStatus.totalSteps > 0 && (
                  <div className="mb-1.5">
                    <div className="h-1 rounded-full overflow-hidden bg-rp-border/20">
                      <div
                        className="h-full rounded-full bg-rp-accent transition-all duration-500"
                        style={{ width: `${Math.max(3, Math.round((wikiStatus.completedSteps / wikiStatus.totalSteps) * 100))}%` }}
                      />
                    </div>
                    <div className="flex justify-between mt-0.5 text-r-2xs text-rp-faint tabular-nums">
                      <span>{wikiStatus.completedSteps}/{wikiStatus.totalSteps}</span>
                      {formatEta(wikiStatus.etaMs) && <span>{formatEta(wikiStatus.etaMs)}</span>}
                    </div>
                  </div>
                )}
                <button
                  onClick={onAction}
                  className="btn-ghost w-full justify-center text-rp-muted hover:text-rp-error hover:bg-rp-error/10"
                >
                  <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round">
                    <rect x="3" y="3" width="10" height="10" rx="1.5" />
                  </svg>
                  Cancel
                </button>
              </div>
            ) : (
              <div className="px-3 py-2.5 space-y-1.5">
                {isCancelled && onRegenerate && (
                  <button
                    onClick={onRegenerate}
                    className="btn-ghost w-full justify-center text-rp-accent hover:bg-rp-accent/10"
                  >
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M1.5 8a6.5 6.5 0 0 1 11.25-4.5M14.5 8a6.5 6.5 0 0 1-11.25 4.5" />
                      <path d="M13.5 1v3.5H10M2.5 15v-3.5H6" />
                    </svg>
                    Regenerate
                  </button>
                )}
                <button
                  onClick={onAction}
                  className="btn-ghost w-full justify-center"
                >
                  {actionLabel === "Resume" ? (
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                      <polygon points="5,3 13,8 5,13" />
                    </svg>
                  ) : (
                    <svg width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round">
                      <path d="M1.5 8a6.5 6.5 0 0 1 11.25-4.5M14.5 8a6.5 6.5 0 0 1-11.25 4.5" />
                      <path d="M13.5 1v3.5H10M2.5 15v-3.5H6" />
                    </svg>
                  )}
                  {actionLabel}
                </button>
              </div>
            )}
          </div>
        )}
      </div>
    </aside>
  );
}

function NavSection({
  title,
  children,
}: {
  title: string;
  children: React.ReactNode;
}) {
  return (
    <section className="mb-3">
      <div className="mb-1 px-2 text-r-2xs font-medium uppercase tracking-wider text-rp-faint">
        {title}
      </div>
      <div className="space-y-0.5">
        {children}
      </div>
    </section>
  );
}

function NavItem({
  page,
  selected,
  onClick,
  subtitle,
  compact = false,
  completed = false,
  generating = false,
}: {
  page: WikiPageSummary;
  selected: boolean;
  onClick: () => void;
  subtitle?: string;
  compact?: boolean;
  completed?: boolean;
  generating?: boolean;
}) {
  const disabled = !completed;
  return (
    <button
      type="button"
      onClick={disabled ? undefined : onClick}
      className={`w-full rounded px-2 py-[5px] text-left transition-colors text-r-sm ${
        disabled
          ? "opacity-30 cursor-default"
          : selected
            ? "bg-rp-hover/60 text-rp-text font-medium"
            : completed && generating
              ? "text-rp-text hover:bg-rp-hover/30"
              : "text-rp-muted hover:bg-rp-hover/30 hover:text-rp-text"
      }`}
    >
      <div className="min-w-0 flex items-center gap-1.5">
        {completed && generating && (
          <svg width="12" height="12" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="shrink-0 text-rp-accent">
            <path d="M3 8.5l3.5 3.5 6.5-8" />
          </svg>
        )}
        <div className="min-w-0 flex-1">
          <div className="truncate">
            {getHumanTitle(page)}
          </div>
          {subtitle ? (
            <div className="mt-0.5 truncate text-r-2xs text-rp-faint">{subtitle}</div>
          ) : !compact ? (
            <div className="mt-0.5 truncate text-r-2xs text-rp-faint">{getShortPath(page.path)}</div>
          ) : null}
        </div>
      </div>
    </button>
  );
}

function EmptyState({ message }: { message: string }) {
  return (
    <div className="rounded-lg px-3 py-2 text-r-sm text-rp-muted">
      {message}
    </div>
  );
}

function getHumanTitle(page: WikiPageSummary): string {
  if (page.pageType === "overview") {
    return "Repository Overview";
  }
  const raw = page.displayTitle || page.title;
  // Strip leading DD labels like "(DD01) " or "(DD01) (DD01) "
  return raw.replace(/^(\(DD\d+\)\s*)+/, "");
}

function getPathDepth(path: string): number {
  return path.split("/").filter(Boolean).length;
}

function getShortPath(path: string): string {
  if (!path) {
    return "";
  }
  return path.length > 42 ? `${path.slice(0, 39)}...` : path;
}

function matchesQuery(page: WikiPageSummary, query: string): boolean {
  if (!query) {
    return true;
  }

  const haystack = `${page.title} ${page.displayTitle || ""} ${page.path} ${page.summary} ${page.displaySummary || ""}`.toLowerCase();
  return haystack.includes(query);
}

function sortPages(a: WikiPageSummary, b: WikiPageSummary): number {
  return getHumanTitle(a).localeCompare(getHumanTitle(b));
}
