import { useBackend } from "../nwb/useBackend";
import type { BackendMode } from "../nwb/useBackend";
import { useNwbData, WINDOW_SAMPLES } from "../nwb/useNwbData";
import { LinePlot } from "./LinePlot";

type Props = {
  title: string;
  description: string;
  mode: BackendMode;
  downloadUrl: string;
  dandisetId: string;
};

// Decimate a long array down to ~maxPoints for light SVG rendering.
const decimate = <T extends { length: number; [i: number]: number }>(
  arr: T,
  maxPoints = 1500,
): number[] => {
  const step = Math.max(1, Math.floor(arr.length / maxPoints));
  const out: number[] = [];
  for (let i = 0; i < arr.length; i += step) out.push(arr[i]);
  return out;
};

export const BackendPanel = ({
  title,
  description,
  mode,
  downloadUrl,
  dandisetId,
}: Props) => {
  const backend = useBackend(downloadUrl, dandisetId, mode);
  const data = useNwbData(backend.file);

  return (
    <div
      style={{
        flex: "1 1 420px",
        minWidth: 380,
        border: "1px solid #d0d0d0",
        borderRadius: 8,
        padding: 16,
        background: "#fafafa",
      }}
    >
      <h3 style={{ marginTop: 0 }}>{title}</h3>
      <p style={{ color: "#555", fontSize: 13, marginTop: 0 }}>{description}</p>

      <div style={{ fontSize: 13, marginBottom: 8 }}>
        <strong>Status:</strong>{" "}
        {backend.status === "opening" && "opening remote file…"}
        {backend.status === "ready" && (
          <span style={{ color: "#1a7f37" }}>
            opened in {backend.openMs?.toFixed(0)} ms
          </span>
        )}
        {backend.status === "error" && (
          <span style={{ color: "#b00020" }}>error</span>
        )}
        {backend.status === "idle" && "idle"}
      </div>

      {backend.resolvedUrl && (
        <div
          style={{
            fontSize: 11,
            color: "#777",
            wordBreak: "break-all",
            marginBottom: 8,
          }}
        >
          <strong>Resolved:</strong> {backend.resolvedUrl}
        </div>
      )}

      {backend.error && (
        <div style={{ color: "#b00020", fontSize: 13, marginBottom: 8 }}>
          {backend.error}
        </div>
      )}

      {backend.status === "ready" && (
        <>
          <div style={{ fontSize: 13, marginBottom: 8 }}>
            <strong>Reading:</strong>{" "}
            {data.done ? (
              data.error ? (
                <span style={{ color: "#b00020" }}>{data.error}</span>
              ) : (
                <span style={{ color: "#1a7f37" }}>complete</span>
              )
            ) : (
              <span>{data.step}…</span>
            )}
          </div>

          {data.rootGroup && (
            <details style={{ marginBottom: 10 }}>
              <summary style={{ cursor: "pointer", fontSize: 13 }}>
                Root group: {data.rootGroup.subgroups.length} groups,{" "}
                {data.rootGroup.datasets.length} datasets
              </summary>
              <div style={{ fontFamily: "monospace", fontSize: 12, marginTop: 6 }}>
                {data.rootGroup.subgroups.map((g) => (
                  <div key={g.path}>📁 {g.name}/</div>
                ))}
                {data.rootGroup.datasets.map((d) => (
                  <div key={d.path}>📄 {d.name}</div>
                ))}
              </div>
            </details>
          )}

          {data.meta && (
            <table style={{ fontSize: 12, marginBottom: 12, lineHeight: 1.5 }}>
              <tbody>
                {Object.entries(data.meta).map(([k, v]) => (
                  <tr key={k}>
                    <td
                      style={{
                        color: "#555",
                        paddingRight: 10,
                        verticalAlign: "top",
                        whiteSpace: "nowrap",
                      }}
                    >
                      {k}
                    </td>
                    <td>{v || <span style={{ color: "#aaa" }}>—</span>}</td>
                  </tr>
                ))}
              </tbody>
            </table>
          )}

          {data.timeseries && (
            <div style={{ marginBottom: 12 }}>
              <div style={{ fontSize: 12, color: "#555", marginBottom: 4 }}>
                Loaded first {data.timeseries.t.length.toLocaleString()} of{" "}
                {data.timeseries.totalSamples.toLocaleString()} samples (
                {(
                  (data.timeseries.t.length / (data.timeseries.totalSamples || 1)) *
                  100
                ).toFixed(2)}
                % of the trace — only those bytes were fetched).
              </div>
              <LinePlot
                xLabel="time (s)"
                yLabel="value"
                series={[
                  {
                    x: decimate(data.timeseries.t),
                    y: decimate(data.timeseries.pupil),
                    color: "#1f77b4",
                    label: "pupil diameter",
                  },
                  {
                    x: decimate(data.timeseries.t),
                    y: decimate(data.timeseries.running),
                    color: "#d62728",
                    label: "running speed",
                  },
                ]}
              />
            </div>
          )}

          {data.trials && (
            <div>
              <div style={{ fontSize: 12, color: "#555", marginBottom: 4 }}>
                Trials table: {data.trials.stimFrequency.length.toLocaleString()}{" "}
                trials — stimulus frequency over the session.
              </div>
              <LinePlot
                xLabel="trial start time (s)"
                yLabel="stim frequency (Hz)"
                series={[
                  {
                    x: decimate(data.trials.startTime),
                    y: decimate(data.trials.stimFrequency),
                    color: "#2ca02c",
                    label: "stim frequency",
                  },
                ]}
              />
            </div>
          )}
        </>
      )}
      <div style={{ fontSize: 11, color: "#999", marginTop: 10 }}>
        Window size: {WINDOW_SAMPLES.toLocaleString()} samples
      </div>
    </div>
  );
};
