"use client";

import React, { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useForm, Controller } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";

// UI bits (shadcn-style)
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import { Separator } from "@/components/ui/separator";
import { Select, SelectTrigger, SelectContent, SelectItem, SelectValue } from "@/components/ui/select";
import { Badge } from "@/components/ui/badge";
import { toast } from "@/components/ui/use-toast";
import { Loader2, Plus, Save, Settings2, X } from "lucide-react";
import { SignOutButton } from "@/components/SignOutButton";

// simple fetch helper
async function jfetch<T = any>(url: string, init?: RequestInit): Promise<T> {
    const res = await fetch(url, {
        ...init,
        headers: {
            "Content-Type": "application/json",
            ...(init?.headers || {}),
        },
        cache: "no-store",
    });
    if (!res.ok) {
        const text = await res.text();
        throw new Error(text || res.statusText);
    }
    return (await res.json()) as T;
}

/** ---------- Types for option endpoints ---------- */
type Opt = { id: string; label: string };

// Finder for options with free-text filter
function useOptions(endpoint: string) {
    const [opts, setOpts] = useState<Opt[]>([]);
    const [loading, setLoading] = useState(false);
    const [q, setQ] = useState("");

    useEffect(() => {
        let alive = true;
        setLoading(true);
        const url = `/api/options/${endpoint}${endpoint.includes("?") ? "&" : "?"}q=${encodeURIComponent(q)}`;
        fetch(url, { cache: "no-store" })
        .then((r) => r.json())
        .then((j) => {
            if (!alive) return;
            setOpts((j?.data as Opt[]) ?? []);
        })
        .catch(() => {
            if (!alive) return;
            setOpts([]);
        })
        .finally(() => alive && setLoading(false));
        return () => {
            alive = false;
        };
    }, [endpoint, q]);

    return { opts, loading, setQ };
}

/** ---------- Form schema ---------- */
const RigSchema = z.object({
    name: z.string().min(1, "Rig name required"),
                           notes: z.string().optional(),
                           // Relations (IDs)
                           laser_source: z.string().min(1, "Laser source required"),
                           laser_software: z.string().min(1, "Software required"),
                           // One of scan lens (with optional aperture & expander) OR focus lens
                           laser_scan_lens: z.string().optional(),
                           laser_scan_lens_apt: z.string().optional(),
                           laser_scan_lens_exp: z.string().optional(),
                           laser_focus_lens: z.string().optional(),
});

type RigForm = z.infer<typeof RigSchema>;

/** ---------- Little select with filter ---------- */
function FilterableSelect({
    label,
    value,
    onValueChange,
    placeholder = "Select…",
    endpoint, // e.g. "laser_source?target=settings_fiber"
}: {
    label: string;
    value?: string;
    onValueChange: (v: string) => void;
    placeholder?: string;
    endpoint: string;
}) {
    const { opts, loading, setQ } = useOptions(endpoint);

    return (
        <div className="space-y-1">
        <Label>{label}</Label>
        <Input
        placeholder="Type to filter…"
        onChange={(e) => setQ(e.target.value)}
        className="mb-1"
        />
        <Select value={value} onValueChange={onValueChange}>
        <SelectTrigger>
        <SelectValue placeholder={loading ? "Loading…" : placeholder} />
        </SelectTrigger>
        <SelectContent>
        {opts.length === 0 && (
            <div className="px-2 py-1 text-sm text-muted-foreground">
            {loading ? "Loading…" : "No matches"}
            </div>
        )}
        {opts.map((o) => (
            <SelectItem key={o.id} value={o.id}>
            {o.label}
            </SelectItem>
        ))}
        </SelectContent>
        </Select>
        </div>
    );
}

/** ---------- Page ---------- */
export default function MyRigsPage() {
    const router = useRouter();
    const searchParams = useSearchParams();
    const [saving, setSaving] = useState(false);
    const [list, setList] = useState<any[]>([]);
    const [loadingList, setLoadingList] = useState(true);

    // Which lens type UI is active: "scan" vs "focus"
    const [lensMode, setLensMode] = useState<"scan" | "focus">("scan");

    const form = useForm<RigForm>({
        resolver: zodResolver(RigSchema),
                                  defaultValues: {
                                      name: "",
                                      notes: "",
                                      laser_source: "",
                                      laser_software: "",
                                      laser_scan_lens: "",
                                      laser_scan_lens_apt: "",
                                      laser_scan_lens_exp: "",
                                      laser_focus_lens: "",
                                  },
    });

    const sourceTarget = "settings_fiber"; // for now default fiber; could be dynamic later

    // Options hooks
    const srcs = useOptions(`laser_source?target=${sourceTarget}`);
    const soft = useOptions("laser_software");
    const scanLens = useOptions(`lens?target=${sourceTarget}`);        // F-theta
    const apertures = useOptions("laser_scan_lens_apt");
    const expanders = useOptions("laser_scan_lens_exp");
    const focusLens = useOptions("lens?target=settings_co2gan");       // focus lens for gantry

    // Load my rigs
    useEffect(() => {
        let alive = true;
        (async () => {
            try {
                setLoadingList(true);
                const res = await jfetch<{ data: any[] }>("/api/rigs/list");
                if (!alive) return;
                setList(res.data || []);
            } catch (e: any) {
                console.warn("[my/rigs] list error", e?.message);
            } finally {
                alive = false ? undefined : setLoadingList(false);
            }
        })();
        return () => {
            alive = false;
        };
    }, []);

    async function onSave(data: RigForm) {
        try {
            setSaving(true);

            // If in focus mode, ensure scan-lens fields are cleared and vice versa.
            const payload: any = { ...data };
            if (lensMode === "focus") {
                payload.laser_scan_lens = null;
                payload.laser_scan_lens_apt = null;
                payload.laser_scan_lens_exp = null;
            } else {
                payload.laser_focus_lens = null;
            }

            const res = await jfetch<{ ok: boolean; id: string }>("/api/rigs/save", {
                method: "POST",
                body: JSON.stringify(payload),
            });

            toast({
                title: "Rig saved",
                description: "Your rig has been saved to your account.",
            });

            // refresh list
            const updated = await jfetch<{ data: any[] }>("/api/rigs/list");
            setList(updated.data || []);

            // clear form (optional)
            form.reset({
                name: "",
                notes: "",
                laser_source: "",
                laser_software: "",
                laser_scan_lens: "",
                laser_scan_lens_apt: "",
                laser_scan_lens_exp: "",
                laser_focus_lens: lensMode === "focus" ? "" : "",
            });
        } catch (e: any) {
            toast({
                title: "Save failed",
                description: e?.message || "Unknown error",
                variant: "destructive",
            });
        } finally {
            setSaving(false);
        }
    }

    function LensModeToggle() {
        return (
            <div className="flex items-center gap-2">
            <Badge
            variant={lensMode === "scan" ? "default" : "secondary"}
            className="cursor-pointer"
            onClick={() => setLensMode("scan")}
            >
            Scan Lens
            </Badge>
            <Badge
            variant={lensMode === "focus" ? "default" : "secondary"}
            className="cursor-pointer"
            onClick={() => setLensMode("focus")}
            >
            Focus Lens
            </Badge>
            </div>
        );
    }

    return (
        <div className="max-w-5xl mx-auto p-4 md:p-6 space-y-6">
        <div className="flex items-center justify-between gap-3 flex-wrap">
        <h1 className="text-2xl font-bold">My Rigs</h1>
        <SignOutButton />
        </div>

        <Card>
        <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle className="flex items-center gap-2">
        <Settings2 className="w-5 h-5" />
        Build a Rig
        </CardTitle>
        <LensModeToggle />
        </CardHeader>
        <CardContent className="space-y-4">
        <form
        onSubmit={form.handleSubmit(onSave)}
        className="grid grid-cols-1 md:grid-cols-2 gap-4"
        >
        <div className="space-y-2">
        <Label>Rig Name *</Label>
        <Input placeholder="e.g., Shop Fiber #1 (20W)" {...form.register("name")} />
        {form.formState.errors.name && (
            <p className="text-sm text-destructive">
            {form.formState.errors.name.message}
            </p>
        )}
        </div>

        <FilterableSelect
        label="Laser Source *"
        endpoint={`laser_source?target=${sourceTarget}`}
        value={form.watch("laser_source")}
        onValueChange={(v) => form.setValue("laser_source", v)}
        />

        <FilterableSelect
        label="Software *"
        endpoint="laser_software"
        value={form.watch("laser_software")}
        onValueChange={(v) => form.setValue("laser_software", v)}
        />

        {lensMode === "scan" ? (
            <>
            <FilterableSelect
            label="Scan Lens (F-theta)"
            endpoint={`lens?target=${sourceTarget}`}
            value={form.watch("laser_scan_lens")}
            onValueChange={(v) => form.setValue("laser_scan_lens", v)}
            />
            <FilterableSelect
            label="Galvo Head Aperture"
            endpoint="laser_scan_lens_apt"
            value={form.watch("laser_scan_lens_apt")}
            onValueChange={(v) => form.setValue("laser_scan_lens_apt", v)}
            />
            <FilterableSelect
            label="Beam Expander (multiplier)"
            endpoint="laser_scan_lens_exp"
            value={form.watch("laser_scan_lens_exp")}
            onValueChange={(v) => form.setValue("laser_scan_lens_exp", v)}
            />
            </>
        ) : (
            <>
            <FilterableSelect
            label="Focus Lens"
            endpoint="lens?target=settings_co2gan"
            value={form.watch("laser_focus_lens")}
            onValueChange={(v) => form.setValue("laser_focus_lens", v)}
            />
            <div className="md:col-span-2">
            <div className="text-sm text-muted-foreground">
            Focus lenses don’t use F-numbers; just pick the lens by name.
            </div>
            </div>
            </>
        )}

        <div className="md:col-span-2">
        <Label>Notes</Label>
        <Textarea rows={3} placeholder="Optional notes about this rig…" {...form.register("notes")} />
        </div>

        <div className="md:col-span-2 flex items-center justify-end gap-2">
        <Button type="submit" disabled={saving}>
        {saving ? <Loader2 className="w-4 h-4 mr-2 animate-spin" /> : <Save className="w-4 h-4 mr-2" />}
        Save Rig
        </Button>
        </div>
        </form>
        </CardContent>
        </Card>

        <Card>
        <CardHeader>
        <CardTitle>Saved Rigs</CardTitle>
        </CardHeader>
        <CardContent>
        {loadingList ? (
            <div className="text-sm text-muted-foreground">Loading…</div>
        ) : list.length === 0 ? (
            <div className="text-sm text-muted-foreground">No rigs saved yet.</div>
        ) : (
            <div className="grid md:grid-cols-2 gap-3">
            {list.map((r) => (
                <div key={r.id} className="border rounded p-3 space-y-1">
                <div className="flex items-center justify-between">
                <div className="font-medium">{r.name}</div>
                </div>
                <div className="text-xs text-muted-foreground">
                Source: {r.laser_source_label || r.laser_source}
                </div>
                <div className="text-xs text-muted-foreground">
                Software: {r.laser_software_label || r.laser_software}
                </div>
                {r.lens_mode === "scan" ? (
                    <>
                    <div className="text-xs text-muted-foreground">
                    Scan Lens: {r.laser_scan_lens_label || r.laser_scan_lens}
                    </div>
                    {r.laser_scan_lens_apt_label && (
                        <div className="text-xs text-muted-foreground">
                        Aperture: {r.laser_scan_lens_apt_label}
                        </div>
                    )}
                    {r.laser_scan_lens_exp_label && (
                        <div className="text-xs text-muted-foreground">
                        Expander: {r.laser_scan_lens_exp_label}
                        </div>
                    )}
                    </>
                ) : r.laser_focus_lens ? (
                    <div className="text-xs text-muted-foreground">
                    Focus Lens: {r.laser_focus_lens_label || r.laser_focus_lens}
                    </div>
                ) : null}
                {r.notes && <div className="text-xs">{r.notes}</div>}
                </div>
            ))}
            </div>
        )}
        </CardContent>
        </Card>
        </div>
    );
}
