"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { categories } from "@/lib/categories";
import { Product } from "@/lib/types";

type FormState = {
  name: string;
  brand: string;
  category: string;
  price: string;
  compareAtPrice: string;
  sku: string;
  image: string;
  shortDescription: string;
  description: string;
  variant: string;
  stock: string;
  featured: boolean;
  popular: boolean;
};

function toFormState(p?: Product): FormState {
  return {
    name: p?.name ?? "",
    brand: p?.brand ?? "Shopp Gadgets",
    category: p?.category ?? categories[0].slug,
    price: p ? String(p.price) : "",
    compareAtPrice: p?.compareAtPrice ? String(p.compareAtPrice) : "",
    sku: p?.sku ?? "",
    image: p?.images?.[0] ?? "",
    shortDescription: p?.shortDescription ?? "",
    description: p?.description ?? "",
    variant: p?.variant ?? "",
    stock: p ? String(p.stock) : "0",
    featured: p?.featured ?? false,
    popular: p?.popular ?? false,
  };
}

export function ProductForm({ product }: { product?: Product }) {
  const [form, setForm] = useState<FormState>(toFormState(product));
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");
  const [uploading, setUploading] = useState(false);
  const [uploadError, setUploadError] = useState("");
  const router = useRouter();
  const isEdit = Boolean(product);

  function set<K extends keyof FormState>(key: K, value: FormState[K]) {
    setForm((f) => ({ ...f, [key]: value }));
  }

  async function handleImageUpload(file: File) {
    setUploading(true);
    setUploadError("");
    try {
      const formData = new FormData();
      formData.append("file", file);
      const res = await fetch("/api/admin/upload-image", {
        method: "POST",
        body: formData,
      });
      const data = await res.json();
      if (!res.ok) {
        setUploadError(data.message || "Couldn't upload that image.");
        return;
      }
      set("image", data.path);
    } catch {
      setUploadError("Something went wrong uploading that image.");
    } finally {
      setUploading(false);
    }
  }

  async function handleSubmit(e: React.FormEvent) {
    e.preventDefault();
    setSaving(true);
    setError("");

    const payload = {
      ...form,
      price: Number(form.price),
      compareAtPrice: form.compareAtPrice ? Number(form.compareAtPrice) : undefined,
      stock: Number(form.stock),
      image: form.image || undefined,
    };

    try {
      const res = await fetch(
        isEdit ? `/api/admin/products/${product!.id}` : "/api/admin/products",
        {
          method: isEdit ? "PUT" : "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        }
      );
      const data = await res.json();
      if (!res.ok) {
        setError(data.message || "Couldn't save this product.");
        setSaving(false);
        return;
      }
      router.push("/admin/products");
      router.refresh();
    } catch {
      setError("Something went wrong. Please try again.");
      setSaving(false);
    }
  }

  return (
    <form onSubmit={handleSubmit} className="flex max-w-2xl flex-col gap-5">
      <div className="grid gap-4 sm:grid-cols-2">
        <TextField label="Product name" value={form.name} onChange={(v) => set("name", v)} required />
        <TextField label="Brand" value={form.brand} onChange={(v) => set("brand", v)} />
      </div>

      <div className="grid gap-4 sm:grid-cols-2">
        <div className="flex flex-col gap-1.5">
          <label className="text-sm font-medium text-brand-ink">Category</label>
          <select
            value={form.category}
            onChange={(e) => set("category", e.target.value)}
            className="rounded-lg border border-black/10 px-3.5 py-2.5 text-sm focus:border-brand-orange focus:outline-none"
          >
            {categories.map((c) => (
              <option key={c.slug} value={c.slug}>
                {c.name}
              </option>
            ))}
          </select>
        </div>
        <TextField label="Variant (optional)" value={form.variant} onChange={(v) => set("variant", v)} placeholder="e.g. 128GB / Black" />
      </div>

      <div className="grid gap-4 sm:grid-cols-3">
        <TextField label="Price (₦)" value={form.price} onChange={(v) => set("price", v)} required type="number" />
        <TextField
          label="Compare-at price (₦, optional)"
          value={form.compareAtPrice}
          onChange={(v) => set("compareAtPrice", v)}
          type="number"
        />
        <TextField label="Stock" value={form.stock} onChange={(v) => set("stock", v)} type="number" />
      </div>

      <TextField label="SKU (optional, auto-generated if left blank)" value={form.sku} onChange={(v) => set("sku", v)} />

      <div className="flex flex-col gap-1.5">
        <label className="text-sm font-medium text-brand-ink">Product photo</label>
        <div className="flex items-center gap-4">
          {form.image && (
            // eslint-disable-next-line @next/next/no-img-element
            <img
              src={form.image}
              alt=""
              className="h-16 w-16 shrink-0 rounded-lg border border-black/10 bg-brand-cream object-cover"
            />
          )}
          <div className="flex-1">
            <input
              type="file"
              accept="image/webp,image/jpeg,image/png,image/gif"
              disabled={uploading}
              onChange={(e) => {
                const file = e.target.files?.[0];
                if (file) handleImageUpload(file);
                e.target.value = "";
              }}
              className="block w-full text-sm text-brand-ink file:mr-3 file:rounded-lg file:border-0 file:bg-brand-ink file:px-4 file:py-2 file:text-sm file:font-semibold file:text-white hover:file:bg-black disabled:opacity-60"
            />
            {uploading && <p className="mt-1.5 text-xs text-black/45">Uploading...</p>}
            {uploadError && <p className="mt-1.5 text-xs text-danger">{uploadError}</p>}
          </div>
        </div>
        <input
          value={form.image}
          onChange={(e) => set("image", e.target.value)}
          placeholder="/images/products/my-product.webp"
          className="mt-1 rounded-lg border border-black/10 px-3.5 py-2.5 text-sm focus:border-brand-orange focus:outline-none"
        />
        <p className="text-xs text-black/45">
          Upload a photo above, or paste an image path directly if you&apos;ve
          already added the file yourself.
        </p>
      </div>

      <TextField
        label="Short description"
        value={form.shortDescription}
        onChange={(v) => set("shortDescription", v)}
        placeholder="One line shown on product cards"
      />

      <div className="flex flex-col gap-1.5">
        <label className="text-sm font-medium text-brand-ink">Full description</label>
        <textarea
          value={form.description}
          onChange={(e) => set("description", e.target.value)}
          rows={4}
          className="rounded-lg border border-black/10 px-3.5 py-2.5 text-sm focus:border-brand-orange focus:outline-none"
        />
      </div>

      <div className="flex gap-6">
        <label className="flex items-center gap-2 text-sm text-brand-ink">
          <input
            type="checkbox"
            checked={form.featured}
            onChange={(e) => set("featured", e.target.checked)}
            className="h-4 w-4 rounded border-black/25 text-brand-orange focus:ring-brand-orange"
          />
          Featured
        </label>
        <label className="flex items-center gap-2 text-sm text-brand-ink">
          <input
            type="checkbox"
            checked={form.popular}
            onChange={(e) => set("popular", e.target.checked)}
            className="h-4 w-4 rounded border-black/25 text-brand-orange focus:ring-brand-orange"
          />
          Popular
        </label>
      </div>

      {error && <p className="text-sm text-danger">{error}</p>}

      <div className="flex gap-3">
        <button
          type="submit"
          disabled={saving}
          className="rounded-lg bg-brand-orange px-5 py-2.5 text-sm font-semibold text-white hover:bg-brand-orange-dark disabled:opacity-60"
        >
          {saving ? "Saving..." : isEdit ? "Save changes" : "Add product"}
        </button>
        <button
          type="button"
          onClick={() => router.push("/admin/products")}
          className="rounded-lg border border-black/10 px-5 py-2.5 text-sm font-semibold text-brand-ink hover:bg-black/5"
        >
          Cancel
        </button>
      </div>
    </form>
  );
}

function TextField({
  label,
  value,
  onChange,
  required,
  type = "text",
  placeholder,
}: {
  label: string;
  value: string;
  onChange: (v: string) => void;
  required?: boolean;
  type?: string;
  placeholder?: string;
}) {
  return (
    <div className="flex flex-col gap-1.5">
      <label className="text-sm font-medium text-brand-ink">{label}</label>
      <input
        type={type}
        value={value}
        required={required}
        placeholder={placeholder}
        onChange={(e) => onChange(e.target.value)}
        className="rounded-lg border border-black/10 px-3.5 py-2.5 text-sm focus:border-brand-orange focus:outline-none"
      />
    </div>
  );
}
