import React, { createElement, useEffect, useMemo, useState } from "react";
import { Box, Text, useApp, useInput } from "ink";
import { formatDuration } from "../../runner/formatting.mjs";
import { formatFileDetail, loadLatestRunArtifact, resolveFileSubject } from "../viewer.mjs";

export function WatchApp({ productDir, serviceFilter = null }) {
  const { exit } = useApp();
  const [artifact, setArtifact] = useState(() => safeLoadArtifact(productDir));
  const [selectedIndex, setSelectedIndex] = useState(0);

  const files = useMemo(() => collectFiles(artifact, serviceFilter), [artifact, serviceFilter]);
  const selected = files[Math.min(selectedIndex, Math.max(0, files.length - 1))] || null;

  useEffect(() => {
    const timer = setInterval(() => {
      setArtifact(safeLoadArtifact(productDir));
    }, 1_000);
    return () => clearInterval(timer);
  }, [productDir]);

  useInput((input, key) => {
    if (input === "q") {
      exit();
      return;
    }
    if (input === "r") {
      setArtifact(safeLoadArtifact(productDir));
      return;
    }
    if (key.downArrow) {
      setSelectedIndex((current) => Math.min(current + 1, Math.max(0, files.length - 1)));
      return;
    }
    if (key.upArrow) {
      setSelectedIndex((current) => Math.max(0, current - 1));
    }
  });

  if (!artifact) {
    return createElement(Text, null, `No run artifact found in ${productDir}`);
  }

  return createElement(
    Box,
    { flexDirection: "column" },
    createElement(
      Text,
      null,
      `testkit watch · q quit · r reload · ${artifact.run.status} · ${formatDuration(artifact.run.durationMs)}`
    ),
    createElement(
      Box,
      { marginTop: 1 },
      createElement(
        Box,
        { width: "40%", flexDirection: "column", marginRight: 2 },
        createElement(Text, null, "Files"),
        ...files.map((entry, index) => {
          const prefix = index === selectedIndex ? ">" : " ";
          return createElement(
            Text,
            { key: `${entry.service.name}:${entry.file.path}` },
            `${prefix} ${entry.file.status.toUpperCase().padEnd(7)} ${entry.file.path}`
          );
        })
      ),
      createElement(
        Box,
        { width: "60%", flexDirection: "column" },
        createElement(Text, null, "Details"),
        ...(selected
          ? formatFileDetail(productDir, artifact, selected, { logTail: 8 })
              .slice(0, 28)
              .map((line, index) => createElement(Text, { key: `${index}:${line}` }, line))
          : [createElement(Text, { key: "empty" }, "No file results")])
      )
    )
  );
}

function safeLoadArtifact(productDir) {
  try {
    return loadLatestRunArtifact(productDir);
  } catch {
    return null;
  }
}

function collectFiles(runArtifact, serviceFilter) {
  if (!runArtifact) return [];
  const entries = [];
  for (const service of runArtifact.services || []) {
    if (serviceFilter && service.name !== serviceFilter) continue;
    for (const suite of service.suites || []) {
      for (const file of suite.files || []) {
        entries.push({ service, suite, file });
      }
    }
  }
  const failed = entries.filter((entry) => entry.file.status === "failed");
  return (failed.length > 0 ? failed : entries).sort((left, right) =>
    left.file.path.localeCompare(right.file.path)
  );
}
