"use client";

import { zodResolver } from "@hookform/resolvers/zod";
import { useRouter } from "next/navigation";
import { useMemo, useState, useTransition } from "react";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { AdminImageUpload } from "@/components/admin/AdminImageUpload";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Select } from "@/components/ui/select";
import { Textarea } from "@/components/ui/textarea";
import type { Brand, Scooter } from "@/lib/mock-data";

const schema = z.object({
  id: z.string().optional(),
  brandId: z.string().min(1),
  name: z.string().min(2),
  slug: z.string().min(2),
  shortDescription: z.string().min(5),
  longDescription: z.string().min(10),
  price: z.coerce.number().int().min(0),
  offerPrice: z.coerce.number().int().min(0),
  rangeKm: z.coerce.number().int().min(0),
  topSpeedKmph: z.coerce.number().int().min(0),
  chargingTime: z.string().min(1),
  battery: z.string().min(1),
  motorPower: z.string().min(1),
  warranty: z.string().min(1),
  colors: z.string().min(1),
  heroImage: z.string().min(1),
  thumbnailImage: z.string().min(1),
  posterImage: z.string().min(1),
  galleryImages: z.string().optional(),
  published: z.boolean().default(true),
});

type ProductFormValues = z.infer<typeof schema>;
type ProductFormInput = z.input<typeof schema>;

type ProductFormProps = {
  brands: Brand[];
  initialProduct?: Partial<Scooter> & { published?: boolean };
  onSave: (values: ProductFormValues) => Promise<{ ok: boolean; message: string }>;
};

export function ProductForm({ brands, initialProduct, onSave }: ProductFormProps) {
  const router = useRouter();
  const [message, setMessage] = useState("");
  const [isPending, startTransition] = useTransition();
  const {
    register,
    handleSubmit,
    setValue,
    watch,
    formState: { errors },
  } = useForm<ProductFormInput, unknown, ProductFormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      id: initialProduct?.id,
      brandId: initialProduct?.brandId ?? brands[0]?.id ?? "",
      name: initialProduct?.name ?? "",
      slug: initialProduct?.slug ?? "",
      shortDescription: initialProduct?.shortDescription ?? "",
      longDescription: initialProduct?.longDescription ?? "",
      price: initialProduct?.price ?? 0,
      offerPrice: initialProduct?.offerPrice ?? 0,
      rangeKm: initialProduct?.rangeKm ?? 0,
      topSpeedKmph: initialProduct?.topSpeedKmph ?? 0,
      chargingTime: initialProduct?.chargingTime ?? "",
      battery: initialProduct?.battery ?? "",
      motorPower: initialProduct?.motorPower ?? "",
      warranty: initialProduct?.warranty ?? "",
      colors: initialProduct?.colors?.join(", ") ?? "",
      heroImage: initialProduct?.heroImage ?? "/images/scooters/new-scooter.png",
      thumbnailImage: initialProduct?.thumbnailImage ?? "/images/scooters/new-scooter-thumb.png",
      posterImage: initialProduct?.posterImage ?? "/images/scooters/new-scooter-poster.png",
      galleryImages:
        initialProduct?.galleryImages?.join("\n") ??
        (initialProduct as any)?.images?.map((image: { url: string }) => image.url).join("\n") ??
        "",
      published: initialProduct?.published ?? true,
    },
  });
  const heroImage = watch("heroImage");
  const thumbnailImage = watch("thumbnailImage");
  const posterImage = watch("posterImage");
  const galleryImagesRaw = watch("galleryImages") ?? "";
  const galleryImages = galleryImagesRaw
    .split("\n")
    .map((item) => item.trim())
    .filter(Boolean);
  const [gallerySlots, setGallerySlots] = useState(() => Math.max(4, galleryImages.length || 0));
  const galleryIndexes = useMemo(
    () => Array.from({ length: gallerySlots }, (_, index) => index),
    [gallerySlots],
  );

  function updateGalleryImage(index: number, url: string) {
    const current = [...galleryImages];
    current[index] = url;
    setValue("galleryImages", current.filter(Boolean).join("\n"), {
      shouldDirty: true,
      shouldValidate: true,
    });
  }

  function submit(values: ProductFormValues) {
    setMessage("");
    startTransition(async () => {
      const result = await onSave(values);
      setMessage(result.message);
      if (result.ok) {
        router.push("/admin/products");
        router.refresh();
      }
    });
  }

  return (
    <form className="soft-card p-5" onSubmit={handleSubmit(submit)}>
      <div className="grid gap-4 md:grid-cols-2">
        <Field label="Brand" error={errors.brandId?.message}>
          <Select {...register("brandId")}>
            {brands.map((brand) => (
              <option key={brand.id} value={brand.id}>
                {brand.name}
              </option>
            ))}
          </Select>
        </Field>
        <Field label="Name" error={errors.name?.message}>
          <Input {...register("name")} />
        </Field>
        <Field label="Slug" error={errors.slug?.message}>
          <Input {...register("slug")} />
        </Field>
        <Field label="Colors" error={errors.colors?.message}>
          <Input {...register("colors")} placeholder="White, Black, Blue" />
        </Field>
        <Field className="md:col-span-2" label="Short Description" error={errors.shortDescription?.message}>
          <Input {...register("shortDescription")} />
        </Field>
        <Field className="md:col-span-2" label="Long Description" error={errors.longDescription?.message}>
          <Textarea {...register("longDescription")} />
        </Field>
        <Field label="Price" error={errors.price?.message}>
          <Input type="number" {...register("price")} />
        </Field>
        <Field label="Offer Price" error={errors.offerPrice?.message}>
          <Input type="number" {...register("offerPrice")} />
        </Field>
        <Field label="Range" error={errors.rangeKm?.message}>
          <Input type="number" {...register("rangeKm")} />
        </Field>
        <Field label="Top Speed" error={errors.topSpeedKmph?.message}>
          <Input type="number" {...register("topSpeedKmph")} />
        </Field>
        <Field label="Charging Time" error={errors.chargingTime?.message}>
          <Input {...register("chargingTime")} />
        </Field>
        <Field label="Battery" error={errors.battery?.message}>
          <Input {...register("battery")} />
        </Field>
        <Field label="Motor Power" error={errors.motorPower?.message}>
          <Input {...register("motorPower")} />
        </Field>
        <Field label="Warranty" error={errors.warranty?.message}>
          <Input {...register("warranty")} />
        </Field>
        <Field label="Hero Image" error={errors.heroImage?.message}>
          <input type="hidden" {...register("heroImage")} />
          <AdminImageUpload
            label="Upload Hero Image"
            previewAlt={`${initialProduct?.name ?? "Scooter"} hero image`}
            value={heroImage}
            onChange={(url) => setValue("heroImage", url, { shouldDirty: true, shouldValidate: true })}
          />
        </Field>
        <Field label="Thumbnail Image" error={errors.thumbnailImage?.message}>
          <input type="hidden" {...register("thumbnailImage")} />
          <AdminImageUpload
            label="Upload Thumbnail Image"
            previewAlt={`${initialProduct?.name ?? "Scooter"} thumbnail image`}
            value={thumbnailImage}
            onChange={(url) => setValue("thumbnailImage", url, { shouldDirty: true, shouldValidate: true })}
          />
        </Field>
        <Field label="Poster Image" error={errors.posterImage?.message}>
          <input type="hidden" {...register("posterImage")} />
          <AdminImageUpload
            label="Upload 3D/AR Poster Image"
            previewAlt={`${initialProduct?.name ?? "Scooter"} poster image`}
            value={posterImage}
            onChange={(url) => setValue("posterImage", url, { shouldDirty: true, shouldValidate: true })}
          />
        </Field>
        <Field className="md:col-span-2" label="Product Gallery Images">
          <input type="hidden" {...register("galleryImages")} />
          <p className="mb-3 text-xs font-medium text-navy-muted">
            Upload gallery images shown on the product detail page. First image appears first in gallery.
          </p>
          <div className="grid gap-3 md:grid-cols-2">
            {galleryIndexes.map((index) => (
              <AdminImageUpload
                key={index}
                label={`Gallery Image ${index + 1}`}
                previewAlt={`${initialProduct?.name ?? "Scooter"} gallery image ${index + 1}`}
                value={galleryImages[index] ?? ""}
                onChange={(url) => updateGalleryImage(index, url)}
              />
            ))}
          </div>
          <button
            type="button"
            onClick={() => setGallerySlots((current) => current + 1)}
            className="mt-3 inline-flex h-10 items-center justify-center rounded-lg border border-primary/35 px-4 text-sm font-bold text-primary transition hover:border-primary hover:bg-primary-soft"
          >
            + Add Gallery Image
          </button>
        </Field>
        <label className="flex items-center gap-2 pt-8 text-sm font-semibold text-navy-deep">
          <input type="checkbox" {...register("published")} />
          Published
        </label>
      </div>
      {message ? <p className="mt-4 rounded-xl bg-primary-soft px-4 py-3 text-sm font-bold text-primary">{message}</p> : null}
      <Button className="mt-5" type="submit" variant="green" disabled={isPending}>
        {isPending ? "Saving..." : "Save Product"}
      </Button>
    </form>
  );
}

function Field({
  label,
  error,
  className,
  children,
}: {
  label: string;
  error?: string;
  className?: string;
  children: React.ReactNode;
}) {
  return (
    <label className={`text-sm font-semibold text-navy-deep ${className ?? ""}`}>
      {label}
      <span className="mt-2 block">{children}</span>
      {error ? <span className="mt-1 block text-xs text-red-600">{error}</span> : null}
    </label>
  );
}
