"use client";

import { useEffect, useRef, useState } from "react";
import {
  MoreHorizontal, Pencil, Trash2, Plus, User, BadgeCheck, ChevronLeft, ChevronRight, CheckCircle2,
} from "lucide-react";
import {
  DropdownMenu, DropdownMenuContent, DropdownMenuItem,
  DropdownMenuSeparator, DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import {
  Select, SelectContent, SelectItem, SelectTrigger, SelectValue,
} from "@/components/ui/select";
import {
  Pagination, PaginationContent, PaginationItem,
} from "@/components/ui/pagination";
import { DataTable, type Column } from "@/components/admin/DataTable";
import { FormSheet } from "@/components/admin/FormSheet";
import { PageHeader } from "@/components/admin/PageHeader";
import { ImageDropZone } from "@/components/admin/ImageDropZone";
import { toast } from "sonner";
import {
  type Inspector, type InspectorPayload,
  getInspectors, createInspector, updateInspector, deleteInspector,
} from "@/services/inspectors";
import { uploadToCloudinary } from "@/lib/cloudinary";
import { ALLOWED_IMAGE_TYPES, MAX_IMAGE_SIZE } from "@/lib/utils";

// ─── Availability config ───────────────────────────────────────────────────────

const AVAILABILITY_COLORS = {
  available: "bg-green-100 text-green-700",
  busy: "bg-yellow-100 text-yellow-700",
  unavailable: "bg-red-100 text-red-700",
};

const AVAILABILITY_LABELS = {
  available: "Available",
  busy: "Busy",
  unavailable: "Unavailable",
};

// ─── Empty form ────────────────────────────────────────────────────────────────

function emptyForm(): InspectorPayload & { id?: number } {
  return {
    inspector_full_name: "",
    specialization: "",
    certifications: [],
    years_of_experience: 0,
    availability: "available",
    inspector_image_url: null,
    inspector_image_public_id: null,
    bio: "",
    inspector_position: 0,
  };
}

// ─── Page ─────────────────────────────────────────────────────────────────────

export default function InspectorsAdminPage() {
  const [inspectors, setInspectors] = useState<Inspector[]>([]);
  const [loading, setLoading] = useState(true);
  const [search, setSearch] = useState("");
  const [page, setPage] = useState(1);
  const [lastPage, setLastPage] = useState(1);
  const [total, setTotal] = useState(0);

  // Sheet state
  const [sheetOpen, setSheetOpen] = useState(false);
  const [editing, setEditing] = useState<(InspectorPayload & { id?: number }) | null>(null);

  // Image upload state
  const [imageFile, setImageFile] = useState<File | null>(null);
  const [imagePreview, setImagePreview] = useState<string | null>(null);
  const [isDragging, setIsDragging] = useState(false);
  const [imageProgress, setImageProgress] = useState<number | null>(null);
  const [imageUploadDone, setImageUploadDone] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Cert tag input
  const [certInput, setCertInput] = useState("");

  const [saving, setSaving] = useState(false);
  const debounceRef = useRef<ReturnType<typeof setTimeout> | null>(null);

  const fetchInspectors = (q: string, p: number) => {
    setLoading(true);
    const params: Record<string, any> = { page: p };
    if (q) params.search = q;
    getInspectors(params)
      .then((res) => {
        setInspectors(res.data);
        setLastPage(res.meta.last_page);
        setTotal(res.meta.total);
      })
      .catch(() => toast.error("Failed to load inspectors."))
      .finally(() => setLoading(false));
  };

  useEffect(() => { fetchInspectors("", 1); }, []);

  const handleSearchChange = (value: string) => {
    setSearch(value);
    setPage(1);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => fetchInspectors(value, 1), 400);
  };

  const handlePageChange = (p: number) => {
    setPage(p);
    fetchInspectors(search, p);
  };

  // ── Image handling ────────────────────────────────────────────────────────
  const handleFileSelect = (file: File) => {
    if (!ALLOWED_IMAGE_TYPES.includes(file.type)) {
      toast.error("Only JPG, PNG, WEBP, or SVG images are allowed.");
      return;
    }
    if (file.size > MAX_IMAGE_SIZE) {
      toast.error("Image must be smaller than 2 MB.");
      return;
    }
    setImageFile(file);
    setImagePreview((prev) => {
      if (prev) URL.revokeObjectURL(prev);
      return URL.createObjectURL(file);
    });
  };

  const handleDragOver = (e: React.DragEvent) => { e.preventDefault(); setIsDragging(true); };
  const handleDragLeave = () => setIsDragging(false);
  const handleDrop = (e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
    const file = e.dataTransfer.files[0];
    if (file) handleFileSelect(file);
  };
  const handleDropzoneClick = () => fileInputRef.current?.click();

  // ── Cert tags ─────────────────────────────────────────────────────────────
  const addCert = () => {
    const trimmed = certInput.trim();
    if (!trimmed || (editing?.certifications ?? []).includes(trimmed)) return;
    setEditing((prev) => prev ? { ...prev, certifications: [...(prev.certifications ?? []), trimmed] } : prev);
    setCertInput("");
  };

  const removeCert = (cert: string) => {
    setEditing((prev) => prev ? { ...prev, certifications: (prev.certifications ?? []).filter((c) => c !== cert) } : prev);
  };

  // ── Open sheet ────────────────────────────────────────────────────────────
  const handleAdd = () => {
    setEditing(emptyForm());
    setImageFile(null);
    setImagePreview(null);
    setImageProgress(null);
    setImageUploadDone(false);
    setCertInput("");
    setSheetOpen(true);
  };

  const handleEdit = (item: Inspector) => {
    setEditing({ ...item });
    setImageFile(null);
    setImagePreview(item.inspector_image_url);
    setImageProgress(null);
    setImageUploadDone(false);
    setCertInput("");
    setSheetOpen(true);
  };

  // ── Save ──────────────────────────────────────────────────────────────────
  const handleSave = async () => {
    if (!editing) return;
    if (!editing.inspector_full_name.trim() || !editing.specialization.trim()) {
      toast.error("Name and specialization are required.");
      return;
    }

    setSaving(true);
    try {
      let imageUrl = editing.inspector_image_url ?? null;
      let imagePublicId = editing.inspector_image_public_id ?? null;

      // Upload image if a new one was selected
      if (imageFile) {
        setImageProgress(0);
        setImageUploadDone(false);
        try {
          const result = await uploadToCloudinary(
            imageFile,
            "image",
            setImageProgress,
            "/api/inspectors/upload-signature",
          );
          imageUrl = result.secure_url;
          imagePublicId = result.public_id;
          setImageProgress(null);
          setImageUploadDone(true);
        } catch {
          setImageProgress(null);
          throw new Error("Image upload failed");
        }
      }

      const payload: InspectorPayload = {
        inspector_full_name: editing.inspector_full_name.trim(),
        specialization: editing.specialization.trim(),
        certifications: editing.certifications ?? [],
        years_of_experience: Number(editing.years_of_experience) || 0,
        availability: editing.availability,
        bio: editing.bio?.trim() || null,
        inspector_image_url: imageUrl,
        inspector_image_public_id: imagePublicId,
        inspector_position: editing.inspector_position ?? 0,
      };

      if (editing.id) {
        await updateInspector(editing.id, payload);
        toast.success("Inspector updated.");
        setSheetOpen(false);
        fetchInspectors(search, page);
        return;
      } else {
        const created = await createInspector(payload);
        setInspectors((prev) => [created, ...prev]);
        setTotal((t) => t + 1);
        toast.success("Inspector added.");
      }

      setSheetOpen(false);
    } catch {
      toast.error("Failed to save inspector.");
    } finally {
      setSaving(false);
    }
  };

  // ── Delete ────────────────────────────────────────────────────────────────
  const handleDelete = async (item: Inspector) => {
    setInspectors((prev) => prev.filter((i) => i.id !== item.id));
    try {
      await deleteInspector(item.id);
      toast.success("Inspector deleted.");
    } catch {
      setInspectors((prev) => [item, ...prev]);
      toast.error("Failed to delete inspector.");
    }
  };

  const columns: Column<Inspector>[] = [
    {
      key: "inspector_full_name",
      label: "Inspector",
      render: (item) => (
        <div className="flex items-center gap-3 min-w-0">
          {item.inspector_image_url ? (
            // eslint-disable-next-line @next/next/no-img-element
            <img src={item.inspector_image_url} alt={item.inspector_full_name} className="h-8 w-8 rounded-full object-cover shrink-0" />
          ) : (
            <div className="h-8 w-8 rounded-full bg-muted flex items-center justify-center shrink-0">
              <User className="h-4 w-4 text-muted-foreground" />
            </div>
          )}
          <div className="min-w-0">
            <p className="font-medium truncate">{item.inspector_full_name}</p>
            <p className="text-xs text-muted-foreground truncate">{item.specialization}</p>
          </div>
        </div>
      ),
    },
    {
      key: "availability",
      label: "Availability",
      render: (item) => (
        <span className={`inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-semibold ${AVAILABILITY_COLORS[item.availability]}`}>
          {AVAILABILITY_LABELS[item.availability]}
        </span>
      ),
      className: "w-32",
    },
    {
      key: "years_of_experience",
      label: "Experience",
      render: (item) => (
        <span className="text-sm text-muted-foreground">{item.years_of_experience} yr{item.years_of_experience !== 1 ? "s" : ""}</span>
      ),
      className: "w-28",
    },
    {
      key: "certifications",
      label: "Certifications",
      render: (item) => (
        <div className="flex flex-wrap gap-1">
          {(item.certifications ?? []).slice(0, 3).map((c) => (
            <span key={c} className="inline-flex items-center gap-1 px-2 py-0.5 rounded-md bg-muted text-xs">
              <BadgeCheck className="h-3 w-3 text-accent" />
              {c}
            </span>
          ))}
          {(item.certifications ?? []).length > 3 && (
            <span className="text-xs text-muted-foreground">+{(item.certifications ?? []).length - 3}</span>
          )}
        </div>
      ),
    },
    {
      key: "actions_inline",
      label: "",
      render: (item) => (
        <DropdownMenu>
          <DropdownMenuTrigger
            className="inline-flex h-8 w-8 items-center justify-center rounded-md opacity-0 transition-opacity group-hover:opacity-100 hover:bg-accent hover:text-accent-foreground focus-visible:outline-none"
            onClick={(e) => e.stopPropagation()}
          >
            <MoreHorizontal className="h-4 w-4" />
          </DropdownMenuTrigger>
          <DropdownMenuContent align="end">
            <DropdownMenuItem onClick={() => handleEdit(item)}>
              <Pencil className="mr-2 h-3.5 w-3.5" /> Edit
            </DropdownMenuItem>
            <DropdownMenuSeparator />
            <DropdownMenuItem
              className="text-destructive focus:text-destructive"
              onClick={() => handleDelete(item)}
            >
              <Trash2 className="mr-2 h-3.5 w-3.5" /> Delete
            </DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      ),
      className: "w-12",
    },
  ];

  return (
    <div className="p-6 lg:p-8 max-w-7xl mx-auto space-y-6">
      <PageHeader
        title="Inspectors"
        description="Manage certified inspection personnel profiles."
        onAdd={handleAdd}
        addLabel="Add Inspector"
      >
        <Badge variant="secondary">{total} total</Badge>
      </PageHeader>

      <DataTable
        data={inspectors}
        columns={columns}
        searchValue={search}
        onSearchChange={handleSearchChange}
        searchPlaceholder="Search by name or specialization…"
        loading={loading}
      />

      {lastPage > 1 && (
        <div className="flex items-center justify-between text-sm text-muted-foreground">
          <span>{total} inspector{total !== 1 ? "s" : ""}</span>
          <Pagination className="mx-0 w-auto justify-end">
            <PaginationContent>
              <PaginationItem>
                <Button variant="outline" size="icon" className="h-8 w-8" onClick={() => handlePageChange(page - 1)} disabled={page <= 1 || loading}>
                  <ChevronLeft className="h-4 w-4" />
                </Button>
              </PaginationItem>
              <PaginationItem>
                <span className="px-3 text-sm">Page {page} of {lastPage}</span>
              </PaginationItem>
              <PaginationItem>
                <Button variant="outline" size="icon" className="h-8 w-8" onClick={() => handlePageChange(page + 1)} disabled={page >= lastPage || loading}>
                  <ChevronRight className="h-4 w-4" />
                </Button>
              </PaginationItem>
            </PaginationContent>
          </Pagination>
        </div>
      )}

      {/* Add / Edit sheet */}
      <FormSheet
        open={sheetOpen}
        onOpenChange={(open) => { if (!open) setSheetOpen(false); }}
        title={editing?.id ? "Edit Inspector" : "Add Inspector"}
        onSave={handleSave}
        saveLabel={saving ? "Saving…" : "Save Inspector"}
        loading={saving}
      >
        {editing && (
          <div className="space-y-5">
            {/* Profile image */}
            <div className="space-y-1.5">
              <Label className="text-xs">Profile Photo</Label>
              <input
                ref={fileInputRef}
                type="file"
                accept="image/*"
                className="hidden"
                onChange={(e) => { const f = e.target.files?.[0]; if (f) handleFileSelect(f); }}
              />
              <ImageDropZone
                preview={imagePreview}
                fallback={editing.inspector_image_url ?? undefined}
                isDragging={isDragging}
                onDragOver={handleDragOver}
                onDragLeave={handleDragLeave}
                onDrop={handleDrop}
                onClick={handleDropzoneClick}
              />
              {imageProgress !== null && (
                <div className="space-y-1 mt-2">
                  <div className="flex justify-between text-xs text-muted-foreground">
                    <span>Uploading image…</span>
                    <span>{imageProgress}%</span>
                  </div>
                  <div className="h-1.5 w-full rounded-full bg-muted overflow-hidden">
                    <div
                      className="h-full bg-primary rounded-full transition-all duration-150"
                      style={{ width: `${imageProgress}%` }}
                    />
                  </div>
                </div>
              )}
              {imageUploadDone && imageProgress === null && (
                <div className="flex items-center gap-1.5 text-xs text-emerald-600 mt-1">
                  <CheckCircle2 className="h-3.5 w-3.5" />
                  <span>Image uploaded</span>
                </div>
              )}
            </div>

            {/* Name */}
            <div className="space-y-1.5">
              <Label className="text-xs">Full Name <span className="text-destructive">*</span></Label>
              <Input
                value={editing.inspector_full_name}
                onChange={(e) => setEditing((p) => p ? { ...p, inspector_full_name: e.target.value } : p)}
                placeholder="e.g. Eng. Tunde Adeyemi"
                className="h-9"
              />
            </div>

            {/* Specialization */}
            <div className="space-y-1.5">
              <Label className="text-xs">Specialization <span className="text-destructive">*</span></Label>
              <Input
                value={editing.specialization}
                onChange={(e) => setEditing((p) => p ? { ...p, specialization: e.target.value } : p)}
                placeholder="e.g. Non-Destructive Testing (NDT)"
                className="h-9"
              />
            </div>

            {/* Experience + Availability side by side */}
            <div className="grid grid-cols-2 gap-3">
              <div className="space-y-1.5">
                <Label className="text-xs">Experience (years)</Label>
                <Input
                  type="number"
                  min={0}
                  value={editing.years_of_experience}
                  onChange={(e) => setEditing((p) => p ? { ...p, years_of_experience: Number(e.target.value) } : p)}
                  className="h-9"
                />
              </div>
              <div className="space-y-1.5">
                <Label className="text-xs">Availability</Label>
                <Select
                  value={editing.availability}
                  onValueChange={(v) => setEditing((p) => p ? { ...p, availability: (v ?? p.availability) as Inspector["availability"] } : p)}
                >
                  <SelectTrigger className="h-9">
                    <SelectValue />
                  </SelectTrigger>
                  <SelectContent>
                    <SelectItem value="available">Available</SelectItem>
                    <SelectItem value="busy">Busy</SelectItem>
                    <SelectItem value="unavailable">Unavailable</SelectItem>
                  </SelectContent>
                </Select>
              </div>
            </div>

            {/* Certifications */}
            <div className="space-y-1.5">
              <Label className="text-xs">Certifications</Label>
              <div className="flex gap-2">
                <Input
                  value={certInput}
                  onChange={(e) => setCertInput(e.target.value)}
                  onKeyDown={(e) => { if (e.key === "Enter") { e.preventDefault(); addCert(); } }}
                  placeholder="e.g. CSWIP 3.1"
                  className="h-9 flex-1"
                />
                <Button type="button" variant="outline" size="sm" className="h-9 shrink-0" onClick={addCert}>
                  <Plus className="h-3.5 w-3.5" />
                </Button>
              </div>
              {(editing.certifications ?? []).length > 0 && (
                <div className="flex flex-wrap gap-1.5 mt-2">
                  {(editing.certifications ?? []).map((c) => (
                    <Badge
                      key={c}
                      variant="secondary"
                      className="gap-1 cursor-pointer hover:bg-destructive/10 hover:text-destructive"
                      onClick={() => removeCert(c)}
                    >
                      {c} ×
                    </Badge>
                  ))}
                </div>
              )}
              <p className="text-xs text-muted-foreground">Press Enter or click + to add. Click a tag to remove.</p>
            </div>

            {/* Bio */}
            <div className="space-y-1.5">
              <Label className="text-xs">Bio</Label>
              <Textarea
                value={editing.bio ?? ""}
                onChange={(e) => setEditing((p) => p ? { ...p, bio: e.target.value } : p)}
                placeholder="Brief professional background…"
                rows={4}
                className="resize-none"
              />
            </div>
          </div>
        )}
      </FormSheet>
    </div>
  );
}
