"use client";

import { useMemo, useRef, useState } from "react";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { api, WorkflowStep } from "@/lib/api";
import { Button, Card } from "@/components/ui";
import { Table, Thead, Tbody, Tr, Th, Td } 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-accent/50 focus:outline-none focus:ring-1 focus:ring-accent/30";

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, isLoading, error: loadError } = 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-4 sm:p-6 lg:p-8">
            <div className="mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
                <div>
                    <h1 className="text-2xl font-bold text-text-primary">Steps</h1>
                    <p className="mt-1 text-sm text-text-secondary">
                        {steps?.length ?? 0} step{steps?.length !== 1 ? "s" : ""} · reusable across all workflows
                    </p>
                </div>
                <div className="flex items-center gap-2">
                    <input ref={fileRef} type="file" accept="application/json" className="hidden" onChange={onImport} />
                    <Button variant="ghost" size="sm" loading={syncing} onClick={onSync}>
                        Sync defaults
                    </Button>
                    <Button variant="ghost" size="sm" loading={importing} onClick={() => fileRef.current?.click()}>
                        Import
                    </Button>
                    <Button variant="primary" size="sm" onClick={openNew}>
                        <svg className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
                            <path strokeLinecap="round" strokeLinejoin="round" d="M12 4.5v15m7.5-7.5h-15" />
                        </svg>
                        New step
                    </Button>
                </div>
            </div>

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

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

            <Card padding={false}>
                {isLoading ? (
                    <div className="flex items-center justify-center py-20">
                        <div className="h-8 w-8 animate-spin rounded-full border-2 border-border border-t-accent" />
                    </div>
                ) : loadError ? (
                    <div className="py-20 text-center text-danger">Failed to load steps. Is the backend running?</div>
                ) : rows.length > 0 ? (
                    <Table>
                        <Thead>
                            <Tr>
                                <Th>Name</Th>
                                <Th>Shell</Th>
                                <Th>Source</Th>
                                <Th>Outputs</Th>
                                <Th>Used by</Th>
                                <Th />
                            </Tr>
                        </Thead>
                        <Tbody>
                            {rows.map((s) => {
                                const count = usage?.[s.step_id] ?? 0;
                                return (
                                    <Tr key={s.step_id}>
                                        <Td label="Name">
                                            <span>
                                                <span className="block font-medium text-text-primary">{s.name}</span>
                                                {s.description && <span className="mt-0.5 block text-xs text-text-secondary">{s.description}</span>}
                                            </span>
                                        </Td>
                                        <Td label="Shell">
                                            <ShellBadge interpreter={s.interpreter} />
                                        </Td>
                                        <Td label="Source">
                                            <span className="rounded-sm border border-border 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 label="Outputs">
                                            <span className="flex flex-wrap gap-1">
                                                {(s.declared_outputs ?? []).length === 0 ? (
                                                    <span className="text-text-tertiary">—</span>
                                                ) : (
                                                    (s.declared_outputs ?? []).map((o) => (
                                                        <span key={o} className="rounded-sm border border-signal/35 px-1.5 py-0.5 font-mono text-[10px] text-signal">
                                                            {o}
                                                        </span>
                                                    ))
                                                )}
                                            </span>
                                        </Td>
                                        <Td label="Used by">
                                            <span className={count === 0 ? "text-text-tertiary" : "text-text-secondary"}>{count === 0 ? "unused" : `${count} workflow${count === 1 ? "" : "s"}`}</span>
                                        </Td>
                                        <Td>
                                            <div className="flex items-center justify-end gap-2">
                                                <Button variant="ghost" size="sm" onClick={() => openEdit(s)}>
                                                    {s.source === "default" ? "View" : "Edit"}
                                                </Button>
                                                <a href={api.exportStepUrl(s.step_id)} download>
                                                    <Button variant="ghost" size="sm">
                                                        Export
                                                    </Button>
                                                </a>
                                            </div>
                                        </Td>
                                    </Tr>
                                );
                            })}
                        </Tbody>
                    </Table>
                ) : (
                    <div className="py-20 text-center">
                        <div className="mx-auto mb-4 flex h-12 w-12 items-center justify-center rounded-full bg-surface-2">
                            <svg className="h-6 w-6 text-text-secondary" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={1.5}>
                                <path strokeLinecap="round" strokeLinejoin="round" d="M6.75 7.5l3 2.25-3 2.25m4.5 0h3m-9 8.25h13.5A2.25 2.25 0 0021 18V6a2.25 2.25 0 00-2.25-2.25H5.25A2.25 2.25 0 003 6v12a2.25 2.25 0 002.25 2.25z" />
                            </svg>
                        </div>
                        <p className="text-text-secondary">{steps && steps.length > 0 ? "No steps match that filter." : "No steps yet."}</p>
                        {(!steps || steps.length === 0) && (
                            <Button variant="primary" size="sm" className="mt-4" onClick={openNew}>
                                Create your first step
                            </Button>
                        )}
                    </div>
                )}
            </Card>

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