"use client";

import { useMemo, useRef, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { api, WorkflowStep } from "@/lib/api";
import { Button } from "@/components/ui";
import { EditStepModal } from "@/components/workflows/EditStepModal";

type Tab = "all" | "bash" | "powershell" | "default" | "shared";

const inputClass =
  "w-full rounded-lg border border-border bg-surface-2 px-3 py-2 text-sm text-text-primary placeholder-text-secondary/50 focus:border-signal focus:outline-none focus:ring-1 focus:ring-signal";

function ShellBadge({ interpreter }: { interpreter: "bash" | "powershell" }) {
  const isBash = interpreter === "bash";
  return (
    <span className={`rounded px-1.5 py-0.5 font-mono text-[10px] uppercase ${isBash ? "bg-bash/15 text-bash" : "bg-pwsh/15 text-pwsh"}`}>
      {isBash ? "bash" : "pwsh"}
    </span>
  );
}

export default function StepsPage() {
  const qc = useQueryClient();
  const { data: steps } = useQuery({ queryKey: ["steps"], queryFn: api.listSteps });
  const { data: usage } = useQuery({ queryKey: ["step-usage"], queryFn: api.stepUsage });

  const [search, setSearch] = useState("");
  const [tab, setTab] = useState<Tab>("all");
  const [editOpen, setEditOpen] = useState(false);
  const [editing, setEditing] = useState<WorkflowStep | null>(null);
  const [importing, setImporting] = useState(false);
  const [syncing, setSyncing] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [notice, setNotice] = useState<string | null>(null);
  const fileRef = useRef<HTMLInputElement>(null);

  const rows = useMemo(() => {
    const q = search.toLowerCase();
    return (steps ?? []).filter((s) => {
      const matchesText = s.name.toLowerCase().includes(q) || (s.description ?? "").toLowerCase().includes(q);
      const matchesTab =
        tab === "all" ||
        (tab === "bash" && s.interpreter === "bash") ||
        (tab === "powershell" && s.interpreter === "powershell") ||
        (tab === "default" && s.source === "default") ||
        (tab === "shared" && s.source !== "default");
      return matchesText && matchesTab;
    });
  }, [steps, search, tab]);

  const openNew = () => {
    setEditing(null);
    setEditOpen(true);
  };
  const openEdit = (s: WorkflowStep) => {
    setEditing(s);
    setEditOpen(true);
  };

  const onImport = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setImporting(true);
    setError(null);
    try {
      const doc = JSON.parse(await file.text());
      await api.importStep(doc);
      qc.invalidateQueries({ queryKey: ["steps"] });
      setNotice("Step imported.");
    } catch (err) {
      setError((err as Error).message);
    } finally {
      setImporting(false);
      e.target.value = "";
    }
  };

  const onSync = async () => {
    setSyncing(true);
    setError(null);
    try {
      const { created, updated } = await api.seedDefaults();
      qc.invalidateQueries({ queryKey: ["steps"] });
      setNotice(`${created} created, ${updated} updated`);
    } catch (err) {
      setError((err as Error).message);
    } finally {
      setSyncing(false);
    }
  };

  return (
    <div className="p-8">
      <div className="mb-6 flex items-center gap-3">
        <div>
          <h1 className="text-xl font-semibold text-text-primary">Steps</h1>
          <p className="text-sm text-text-secondary">Reusable steps shared across all workflows.</p>
        </div>
        <div className="ml-auto flex items-center gap-2">
          <input ref={fileRef} type="file" accept="application/json" className="hidden" onChange={onImport} />
          <Button variant="secondary" size="sm" loading={syncing} onClick={onSync}>
            Sync defaults
          </Button>
          <Button variant="secondary" size="sm" loading={importing} onClick={() => fileRef.current?.click()}>
            Import
          </Button>
          <Button size="sm" onClick={openNew}>
            + New step
          </Button>
        </div>
      </div>

      {error && <div className="mb-4 rounded border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">{error}</div>}
      {notice && <div className="mb-4 rounded border border-signal/30 bg-signal/10 px-3 py-2 text-sm text-signal">{notice}</div>}

      <div className="mb-4 flex items-center gap-2">
        <input className={`${inputClass} max-w-sm`} placeholder="Search steps…" value={search} onChange={(e) => setSearch(e.target.value)} />
        <div className="flex gap-1.5">
          {(["all", "bash", "powershell", "default", "shared"] as Tab[]).map((t) => (
            <button
              key={t}
              onClick={() => setTab(t)}
              className={`rounded-full border px-3 py-1 text-xs capitalize ${
                tab === t ? "border-signal/50 bg-signal/15 text-signal" : "border-border bg-surface-2 text-text-secondary hover:text-text-primary"
              }`}
            >
              {t === "powershell" ? "PowerShell" : t}
            </button>
          ))}
        </div>
      </div>

      <div className="overflow-x-auto rounded-lg border border-border">
        <table className="w-full text-sm">
          <thead>
            <tr className="border-b border-border text-left text-[11px] uppercase tracking-wide text-text-secondary">
              <th className="px-4 py-2.5 font-bold">Name</th>
              <th className="px-4 py-2.5 font-bold">Shell</th>
              <th className="px-4 py-2.5 font-bold">Source</th>
              <th className="px-4 py-2.5 font-bold">Outputs</th>
              <th className="px-4 py-2.5 font-bold">Used by</th>
              <th className="px-4 py-2.5 text-right font-bold">Actions</th>
            </tr>
          </thead>
          <tbody>
            {rows.map((s) => {
              const count = usage?.[s.step_id] ?? 0;
              return (
                <tr key={s.step_id} className="border-b border-border last:border-0">
                  <td className="px-4 py-3">
                    <div className="font-medium text-text-primary">{s.name}</div>
                    {s.description && <div className="text-xs text-text-secondary">{s.description}</div>}
                  </td>
                  <td className="px-4 py-3">
                    <ShellBadge interpreter={s.interpreter} />
                  </td>
                  <td className="px-4 py-3">
                    <span className="rounded bg-surface-2 px-1.5 py-0.5 font-mono text-[10px] uppercase text-text-secondary">
                      {s.source === "default" ? "default" : "shared"}
                    </span>
                  </td>
                  <td className="px-4 py-3">
                    <div className="flex flex-wrap gap-1">
                      {(s.declared_outputs ?? []).map((o) => (
                        <span key={o} className="rounded border border-signal/35 px-1.5 py-0.5 font-mono text-[10px] text-signal">
                          {o}
                        </span>
                      ))}
                    </div>
                  </td>
                  <td className="px-4 py-3 text-text-secondary">
                    {count === 0 ? "0" : `${count} workflow${count === 1 ? "" : "s"}`}
                  </td>
                  <td className="px-4 py-3 text-right">
                    <div className="flex items-center justify-end gap-3 text-text-secondary">
                      <button onClick={() => openEdit(s)} className="hover:text-text-primary">
                        Edit
                      </button>
                      <a href={api.exportStepUrl(s.step_id)} download className="hover:text-text-primary">
                        Export
                      </a>
                      <button onClick={() => openEdit(s)} className="hover:text-danger">
                        Delete
                      </button>
                    </div>
                  </td>
                </tr>
              );
            })}
            {rows.length === 0 && (
              <tr>
                <td colSpan={6} className="px-4 py-8 text-center text-sm text-text-secondary">
                  No steps found.
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      <EditStepModal
        key={editing?.step_id ?? "new"}
        open={editOpen}
        step={editing}
        onClose={() => {
          setEditOpen(false);
          qc.invalidateQueries({ queryKey: ["steps"] });
          qc.invalidateQueries({ queryKey: ["step-usage"] });
        }}
      />
    </div>
  );
}
