"use client";

import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useQuery } from "@tanstack/react-query";
import { api, Workflow } from "@/lib/api";
import { Button, Modal } from "@/components/ui";
import { ScheduleCard } from "./ScheduleCard";
import { DualListBox } from "./DualListBox";

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

export function EditWorkflowModal({ open, workflow, onSaved, onClose }: { open: boolean; workflow: Workflow; onSaved: (w: Workflow) => void; onClose: () => void }) {
    const router = useRouter();
    const [name, setName] = useState(workflow.name);
    const [targets, setTargets] = useState<string[]>(workflow.target_server_ids);
    // Rows rather than a map: a half-typed key is not a valid map entry, and
    // rebuilding the map on every keystroke would drop a row the moment its key
    // was cleared. Only complete pairs are written back on save.
    const [tagRows, setTagRows] = useState<[string, string][]>(Object.entries(workflow.target_tags ?? {}));
    const [busy, setBusy] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const { data: servers } = useQuery({ queryKey: ["servers"], queryFn: () => api.listServers() });
    const { data: knownTags } = useQuery({ queryKey: ["server-tags"], queryFn: () => api.listKnownTags(), staleTime: 60_000 });

    useEffect(() => {
        if (open) {
            setName(workflow.name);
            setTargets(workflow.target_server_ids);
            setTagRows(Object.entries(workflow.target_tags ?? {}));
        }
    }, [open, workflow]);

    const save = async () => {
        setBusy(true);
        setError(null);
        try {
            const updated = await api.updateWorkflow(workflow.workflow_id, {
                ...workflow,
                name,
                target_server_ids: targets,
                target_tags: Object.fromEntries(tagRows.filter(([k, v]) => k && v)),
            });
            onSaved(updated);
            onClose();
        } catch (e) {
            setError((e as Error).message);
        } finally {
            setBusy(false);
        }
    };

    const del = async () => {
        if (!window.confirm("Delete this workflow? This cannot be undone.")) return;
        setBusy(true);
        setError(null);
        try {
            await api.deleteWorkflow(workflow.workflow_id);
            router.push("/workflows");
        } catch (e) {
            setError((e as Error).message);
            setBusy(false);
        }
    };

    return (
        <Modal open={open} onClose={onClose} title="Edit workflow" wide>
            <div className="space-y-4">
                {error && <div className="rounded border border-danger/30 bg-danger/10 px-3 py-2 text-sm text-danger">{error}</div>}
                <div>
                    <label className="mb-1 block text-xs uppercase text-text-secondary">Name</label>
                    <input className={inputClass} value={name} onChange={(e) => setName(e.target.value)} />
                </div>
                <div>
                    <label className="mb-1 block text-xs uppercase text-text-secondary">Target servers</label>
                    {servers && servers.length === 0 ? (
                        <p className="text-xs text-text-secondary">No servers registered.</p>
                    ) : (
                        <DualListBox
                            items={(servers ?? []).map((s) => ({ id: s.server_id, label: s.hostname, hint: s.status === "active" ? undefined : s.status }))}
                            selected={targets}
                            onChange={setTargets}
                            selectedLabel="Targets"
                            emptyAvailable="Every server is a target."
                            emptySelected="No servers targeted."
                        />
                    )}
                    <p className="mt-1.5 text-[11px] text-text-tertiary">Click to highlight, ctrl-click for several, double-click to move.</p>
                </div>

                <div className="border-t border-border-soft pt-4">
                    <label className="mb-1 block text-xs uppercase text-text-secondary">Target tags</label>
                    <p className="mb-2 text-[11px] text-text-tertiary">
                        Anything carrying <em>every</em> tag below runs too, on top of the servers named above. Leave empty to run only the named ones.
                    </p>

                    <datalist id="workflow-tag-keys">
                        {Object.keys(knownTags ?? {}).map((k) => (
                            <option key={k} value={k} />
                        ))}
                    </datalist>
                    <datalist id="workflow-tag-values">
                        {Object.values(knownTags ?? {})
                            .flat()
                            .map((v) => (
                                <option key={v} value={v} />
                            ))}
                    </datalist>

                    <div className="flex flex-col gap-2">
                        {tagRows.map(([k, v], i) => (
                            <div key={i} className="flex items-center gap-2">
                                <input
                                    list="workflow-tag-keys"
                                    value={k}
                                    onChange={(e) => setTagRows(tagRows.map((row, j): [string, string] => (j === i ? [e.target.value, row[1]] : row)))}
                                    placeholder="env"
                                    className="w-32 rounded-lg border border-border bg-surface-2 px-2 py-1 font-mono text-xs text-text-primary focus:border-signal focus:outline-none"
                                />
                                <span className="font-mono text-text-tertiary">:</span>
                                <input
                                    list="workflow-tag-values"
                                    value={v}
                                    onChange={(e) => setTagRows(tagRows.map((row, j): [string, string] => (j === i ? [row[0], e.target.value] : row)))}
                                    placeholder="prod"
                                    className="w-36 rounded-lg border border-border bg-surface-2 px-2 py-1 font-mono text-xs text-text-primary focus:border-signal focus:outline-none"
                                />
                                <button
                                    type="button"
                                    onClick={() => setTagRows(tagRows.filter((_, j) => j !== i))}
                                    className="text-xs text-text-tertiary hover:text-danger focus:outline-none focus-visible:ring-2 focus-visible:ring-signal"
                                    aria-label={`Remove ${k || "tag"}`}
                                >
                                    Remove
                                </button>
                            </div>
                        ))}
                        {tagRows.length === 0 && <p className="text-xs text-text-secondary">No tag selector — only the named servers will run.</p>}
                    </div>

                    {tagRows.length < 20 && (
                        <button
                            type="button"
                            onClick={() => setTagRows([...tagRows, ["", ""] as [string, string]])}
                            className="mt-2 text-xs text-signal hover:underline focus:outline-none focus-visible:ring-2 focus-visible:ring-signal"
                        >
                            Add tag
                        </button>
                    )}
                </div>
                {/* The schedule saves through its own endpoint, so it sits above
                    the footer rather than under it — the footer's Save covers the
                    name and targets only, and the two are labelled accordingly. */}
                <ScheduleCard workflow={workflow} />

                <div className="flex items-center justify-between border-t border-border-soft pt-4">
                    <Button variant="danger" onClick={del} loading={busy}>
                        Delete workflow
                    </Button>
                    <div className="flex gap-2">
                        <Button variant="ghost" onClick={onClose}>
                            Cancel
                        </Button>
                        <Button variant="primary" onClick={save} loading={busy} disabled={!name.trim()}>
                            Save workflow
                        </Button>
                    </div>
                </div>
            </div>
        </Modal>
    );
}
