import { LogDto, TraceWithLogsDto } from "@montelo/browser-client";
import { GanttChart } from "lucide-react";
import React, { FC, useEffect, useRef, useState } from "react";
import { ScrollArea } from "../ui/scroll-area";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip";
import { SourceToIconMap } from "./SourceToIconMap";
import { buildTree } from "./utils";

type Props = {
  trace: TraceWithLogsDto;
  selectedId: string;
  handleSelect: (id: string) => void;
};

const LogTreeNode: FC<{
  Icon?: React.ReactNode;
  log: LogDto;
  onSelect: (id: string) => void;
  selectedId: string;
  depth: number;
}> = ({ log, onSelect, selectedId, depth, Icon }) => {
  const isNodeSelected = selectedId === log.id;

  const handleClick = () => {
    if (isNodeSelected) {
      return;
    }
    onSelect(log.id);
  };

  const moveRightBy = (depth + 1) * 14;

  return (
    <div
      className={`
      hover:bg-secondary
      my-1
      cursor-pointer 
      rounded-xl
      px-4
      py-2
      ${isNodeSelected ? "bg-secondary" : ""} 
      `}
      style={{
        paddingLeft: depth ? `${moveRightBy}px` : "",
      }}
      onClick={handleClick}
    >
      <div className="flex items-center gap-2">
        {Icon || SourceToIconMap[log.source]}
        <div className={`${log.duration ? "max-w-32" : "max-w-40"} overflow-hidden`}>
          <TooltipProvider delayDuration={0}>
            <Tooltip>
              <TooltipTrigger asChild>
                <span className="block truncate text-sm">{log.name}</span>
              </TooltipTrigger>
              <TooltipContent className="relative z-10 bg-slate-500">
                <p>{log.name}</p>
              </TooltipContent>
            </Tooltip>
          </TooltipProvider>
        </div>
        <span className="text-muted-foreground text-xs">{log.duration ? `${log.duration}s` : ""}</span>
      </div>
    </div>
  );
};

export const LogsTreeView: FC<Props> = ({ trace, selectedId, handleSelect }) => {
  // build the tree of logs
  const logs = trace.logs;
  const treeLogs = buildTree(logs);

  // offset calculations
  const containerRef = useRef<HTMLDivElement>(null);
  const [offsetTop, setOffsetTop] = useState(0);
  useEffect(() => {
    if (containerRef.current) {
      const rect = containerRef.current.getBoundingClientRect();
      setOffsetTop(rect.top);
    }
  }, []);

  return (
    <div>
      <div className={"mb-2"}>
        <h1 className={"text-xl"}>Trace</h1>
      </div>
      <ScrollArea>
        <div ref={containerRef} style={{ minHeight: `calc(100vh - ${offsetTop}px - 16px)` }}>
          <LogTreeNode
            key={trace.id}
            log={trace as any}
            onSelect={handleSelect}
            selectedId={selectedId}
            depth={0}
            Icon={
              <div className="bg-primary h-6 w-6 rounded p-1">
                <GanttChart className="h-full w-full" />
              </div>
            }
          />
          {treeLogs.map((log) => (
            <LogTreeNode key={log.id} log={log} onSelect={handleSelect} selectedId={selectedId} depth={log.depth} />
          ))}
        </div>
      </ScrollArea>
    </div>
  );
};
