"use client";

import * as React from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import { Eye, EyeOff, RefreshCw } from "lucide-react";
import { Button } from "@/components/ui/button";
import { Input, Field, NativeSelect } from "@/components/ui/input";
import { createWorker, updateWorker, type WorkerInput } from "@/lib/actions/workers";

export function WorkerForm({ id, initial, roles, passwordMinLength }: { id?: string; initial?: Partial<WorkerInput>; roles: { id: string; key: string; name: string; description: string | null }[]; passwordMinLength: number }) {
  const router = useRouter();
  const [busy, setBusy] = React.useState(false);
  const [show, setShow] = React.useState(false);
  const [f, setF] = React.useState({ fullName: initial?.fullName ?? "", email: initial?.email ?? "", username: initial?.username ?? "", phone: initial?.phone ?? "", emergencyContact: initial?.emergencyContact ?? "", roleId: initial?.roleId ?? roles.find((r) => r.key === "RECEPTION")?.id ?? roles[0]?.id ?? "", hireDate: initial?.hireDate ?? "", password: "", locale: (initial?.locale as "en" | "fr" | "ar") ?? "en" });
  const upd = <K extends keyof typeof f>(k: K, v: (typeof f)[K]) => setF((s) => ({ ...s, [k]: v }));
  function generate() {
    const chars = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789!@#";
    let p = "";
    for (let i = 0; i < 12; i++) p += chars[Math.floor(Math.random() * chars.length)];
    upd("password", p);
    setShow(true);
  }
  async function submit(e: React.FormEvent) {
    e.preventDefault();
    setBusy(true);
    const payload: WorkerInput = { ...f, username: f.username || null, phone: f.phone || null, emergencyContact: f.emergencyContact || null, hireDate: f.hireDate || null, password: f.password || undefined };
    const res = id ? await updateWorker(id, payload) : await createWorker(payload);
    setBusy(false);
    if (!res.ok) return toast.error(res.error);
    toast.success(id ? "Worker updated" : "Worker created");
    router.push(`/workers/${id ?? (res.data as { id: string }).id}`);
  }
  const role = roles.find((r) => r.id === f.roleId);
  return (
    <form onSubmit={submit} className="space-y-5">
      <div className="grid gap-4 sm:grid-cols-2">
        <Field label="Full name" required>
          <Input value={f.fullName} onChange={(e) => upd("fullName", e.target.value)} autoFocus />
        </Field>
        <Field label="Email" required hint="Used to sign in">
          <Input type="email" value={f.email} onChange={(e) => upd("email", e.target.value)} />
        </Field>
        <Field label="Username" hint="Optional alternative login">
          <Input value={f.username ?? ""} onChange={(e) => upd("username", e.target.value)} className="font-mono" />
        </Field>
        <Field label="Phone">
          <Input type="tel" value={f.phone ?? ""} onChange={(e) => upd("phone", e.target.value)} />
        </Field>
        <Field label="Emergency contact" hint="Name and phone, shown to admins only">
          <Input value={f.emergencyContact} onChange={(e) => upd("emergencyContact", e.target.value)} placeholder="e.g. Amina (sister) · +212 6…" />
        </Field>
        <Field label="Role" required hint={role?.description ?? undefined}>
          <NativeSelect value={f.roleId} onChange={(e) => upd("roleId", e.target.value)}>
            {roles.map((r) => (
              <option key={r.id} value={r.id}>
                {r.name}
              </option>
            ))}
          </NativeSelect>
        </Field>
        <Field label="Hire date">
          <Input type="date" value={f.hireDate ?? ""} onChange={(e) => upd("hireDate", e.target.value)} />
        </Field>
        <Field label="Interface language">
          <NativeSelect value={f.locale} onChange={(e) => upd("locale", e.target.value as "en" | "fr" | "ar")}>
            <option value="en">English</option>
            <option value="fr">Français</option>
            <option value="ar">العربية</option>
          </NativeSelect>
        </Field>
        <Field label={id ? "New password" : "Temporary password"} required={!id} hint={id ? "Leave empty to keep the current password. Setting one signs the worker out everywhere." : `At least ${passwordMinLength} characters. Share it securely; the worker can change it in their profile.`}>
          <div className="flex gap-1.5">
            <div className="relative flex-1">
              <Input type={show ? "text" : "password"} value={f.password} onChange={(e) => upd("password", e.target.value)} autoComplete="new-password" className="pr-9 font-mono" />
              <button type="button" onClick={() => setShow((s) => !s)} className="absolute right-2 top-1/2 -translate-y-1/2 rounded p-1 text-fg-subtle hover:text-fg" aria-label="Toggle visibility">
                {show ? <EyeOff className="size-4" /> : <Eye className="size-4" />}
              </button>
            </div>
            <Button type="button" variant="secondary" size="icon" onClick={generate} title="Generate">
              <RefreshCw />
            </Button>
          </div>
        </Field>
      </div>
      <div className="flex justify-end gap-2">
        <Button type="button" variant="secondary" onClick={() => router.back()}>
          Cancel
        </Button>
        <Button type="submit" loading={busy}>
          {id ? "Save changes" : "Create account"}
        </Button>
      </div>
    </form>
  );
}
