"use client";

import { useEffect, useMemo, useState } from "react";
import { Boxes, FileCheck2, PlusCircle, Upload } from "lucide-react";
import type { UseFormReturn } from "react-hook-form";
import { cn } from "@/lib/utils";
import { catalogApi } from "@/lib/api/catalog";
import type { ApiCategory, ApiProduct } from "@/lib/api/types";
import type { SellerWizardValues } from "./seller.schema";
import type { SavedDocuments } from "./page";

const uploadModes = [
  {
    value: "existing",
    title: "Existing Products",
    description: "Map products from your current catalog.",
    icon: Boxes,
  },
  {
    value: "new",
    title: "New Product",
    description: "Create a new product listing manually.",
    icon: PlusCircle,
  },
  {
    value: "bulk",
    title: "Bulk Upload",
    description: "Upload product sheet in one go.",
    icon: Upload,
  },
] as const;

/** Chosen when the trade is not one Biznie already lists. */
const OTHER = "__other__";

function ErrorText({ message }: { message?: string }) {
  if (!message) return null;
  return <p className="mt-1 text-xs text-red-600">{message}</p>;
}

export default function StepProducts({
  form,
  savedDocuments = {},
}: {
  form: UseFormReturn<SellerWizardValues>;
  savedDocuments?: SavedDocuments;
}) {
  const {
    register,
    setValue,
    watch,
    formState: { errors },
  } = form;

  const selectedMode = watch("product_upload_mode");
  const category = watch("category");
  const products = watch("products");
  const productSheet = watch("product_sheet") as File | null;

  const [categories, setCategories] = useState<ApiCategory[]>([]);
  const [catalogProducts, setCatalogProducts] = useState<ApiProduct[]>([]);

  /* Whether the category box is a picker or a free-text field. */
  const [customCategory, setCustomCategory] = useState(false);

  useEffect(() => {
    catalogApi
      .categories({ per_page: 100 })
      .then((res) => setCategories(res.data ?? []))
      .catch(() => setCategories([]));
  }, []);

  const matchedCategory = useMemo(
    () => categories.find((item) => item.name.toLowerCase() === (category ?? "").toLowerCase()),
    [categories, category]
  );

  // Once a category Biznie carries is named, suggest the products under it.
  useEffect(() => {
    if (!matchedCategory) {
      setCatalogProducts([]);
      return;
    }
    catalogApi
      .products({ category_id: matchedCategory.id, per_page: 100 })
      .then((res) => setCatalogProducts(res.data ?? []))
      .catch(() => setCatalogProducts([]));
  }, [matchedCategory]);

  const selectedProducts = useMemo(
    () =>
      (products ?? "")
        .split(",")
        .map((entry) => entry.trim())
        .filter(Boolean),
    [products]
  );

  const toggleProduct = (name: string) => {
    const next = selectedProducts.includes(name)
      ? selectedProducts.filter((entry) => entry !== name)
      : [...selectedProducts, name];
    setValue("products", next.join(", "), { shouldValidate: true, shouldDirty: true });
  };

  const useCustomCategory = customCategory || (Boolean(category) && !matchedCategory);

  return (
    <div className="rounded-xl bg-white p-5 shadow-sm ring-1 ring-gray-100">
      <h3 className="mb-4 text-sm font-semibold text-gray-900">Store &amp; Products</h3>

      <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
        <div>
          <label className="mb-1 block text-xs font-medium text-gray-700">
            Category <span className="text-red-500">*</span>
          </label>

          {useCustomCategory ? (
            <div className="flex gap-2">
              <input
                {...register("category")}
                className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none focus:ring-1 focus:ring-[#CC1414]"
                placeholder="Enter your category"
              />
              {categories.length > 0 && (
                <button
                  type="button"
                  onClick={() => {
                    setCustomCategory(false);
                    setValue("category", "", { shouldValidate: true, shouldDirty: true });
                  }}
                  className="shrink-0 rounded-lg border border-gray-200 px-3 py-2 text-xs font-medium text-gray-600 hover:border-[#CC1414] hover:text-[#CC1414]"
                >
                  Pick from list
                </button>
              )}
            </div>
          ) : (
            <select
              value={matchedCategory ? matchedCategory.name : ""}
              onChange={(event) => {
                if (event.target.value === OTHER) {
                  setCustomCategory(true);
                  setValue("category", "", { shouldValidate: true, shouldDirty: true });
                  return;
                }
                setValue("category", event.target.value, { shouldValidate: true, shouldDirty: true });
                setValue("products", "", { shouldDirty: true });
              }}
              className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none focus:ring-1 focus:ring-[#CC1414]"
            >
              <option value="">Select category</option>
              {categories.map((item) => (
                <option key={item.id} value={item.name}>
                  {item.name}
                </option>
              ))}
              <option value={OTHER}>Other (enter my own)</option>
            </select>
          )}
          <ErrorText message={errors.category?.message} />
        </div>

        <div>
          {/* No asterisk: turnover is context for the reviewer, not a gate. */}
          <label className="mb-1 block text-xs font-medium text-gray-700">Turnover</label>
          <input
            {...register("turnover")}
            className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none focus:ring-1 focus:ring-[#CC1414]"
            placeholder="e.g. 1 Cr - 5 Cr"
          />
          <ErrorText message={errors.turnover?.message} />
        </div>

        <div className="md:col-span-2">
          <label className="mb-1 block text-xs font-medium text-gray-700">
            Products <span className="text-red-500">*</span>
          </label>

          {/* Suggestions only exist for a category Biznie already carries;
              otherwise the textarea below is the whole story. */}
          {catalogProducts.length > 0 && (
            <div className="mb-2 flex flex-wrap gap-2">
              {catalogProducts.map((product) => {
                const active = selectedProducts.includes(product.name);
                return (
                  <button
                    key={product.id}
                    type="button"
                    onClick={() => toggleProduct(product.name)}
                    aria-pressed={active}
                    className={cn(
                      "rounded-lg border px-3 py-1.5 text-xs font-medium transition",
                      active
                        ? "border-[#CC1414] bg-rose-50 text-[#CC1414]"
                        : "border-gray-200 bg-white text-gray-600 hover:border-[#CC1414]/50"
                    )}
                  >
                    {product.name}
                  </button>
                );
              })}
            </div>
          )}

          <textarea
            {...register("products")}
            rows={4}
            className="w-full rounded-lg border border-gray-200 px-3 py-2 text-sm focus:border-[#CC1414] focus:outline-none focus:ring-1 focus:ring-[#CC1414]"
            placeholder="List your key products, separated by commas"
          />
          <ErrorText message={errors.products?.message} />
        </div>
      </div>

      <div className="mt-6">
        <p className="mb-2 text-xs font-medium text-gray-700">
          Product Upload Options <span className="text-red-500">*</span>
        </p>
        <div className="grid grid-cols-1 gap-3 md:grid-cols-3">
          {uploadModes.map((mode) => {
            const Icon = mode.icon;
            const selected = selectedMode === mode.value;
            return (
              <button
                key={mode.value}
                type="button"
                onClick={() =>
                  setValue("product_upload_mode", mode.value, {
                    shouldValidate: true,
                    shouldDirty: true,
                  })
                }
                aria-pressed={selected}
                className={cn(
                  "rounded-xl border p-4 text-left shadow-sm transition",
                  selected
                    ? "border-[#CC1414] bg-rose-50 ring-1 ring-[#CC1414]/20"
                    : "border-gray-200 bg-white hover:border-[#CC1414]/50"
                )}
              >
                <div className="mb-2 flex items-center gap-2 text-sm font-semibold text-gray-900">
                  <Icon className={cn("h-4 w-4", selected ? "text-[#CC1414]" : "text-gray-500")} />
                  {mode.title}
                </div>
                <p className="text-xs text-gray-600">{mode.description}</p>
              </button>
            );
          })}
        </div>
        <ErrorText message={errors.product_upload_mode?.message} />

        {/* Each option now leads somewhere rather than only recording a choice. */}
        <div className="mt-3 rounded-xl border border-gray-200 bg-gray-50 p-4">
          {selectedMode === "existing" && (
            <p className="text-xs text-gray-600">
              {matchedCategory
                ? "Tap the products above to map them from the Biznie catalogue. Anything missing can be typed into the Products box."
                : "Pick a category Biznie already carries to map products from the catalogue, or choose “New Product” to list your own."}
            </p>
          )}

          {selectedMode === "new" && (
            <p className="text-xs text-gray-600">
              List each product you want to sell in the Products box above (comma separated). Our
              team will create the listings for you once your application is approved.
            </p>
          )}

          {selectedMode === "bulk" && (
            <div>
              <label
                htmlFor="product-sheet"
                className="flex cursor-pointer items-center gap-2 rounded-lg border border-dashed border-gray-300 bg-white px-3 py-3 text-xs text-gray-600 transition hover:border-[#CC1414]"
              >
                {productSheet || savedDocuments.product_sheet ? (
                  <FileCheck2 className="h-4 w-4 text-[#CC1414]" />
                ) : (
                  <Upload className="h-4 w-4" />
                )}
                <span>
                  {productSheet
                    ? productSheet.name
                    : savedDocuments.product_sheet
                      ? "Sheet uploaded — click to replace"
                      : "Upload your product sheet (CSV or Excel, up to 10 MB)"}
                </span>
              </label>
              <input
                id="product-sheet"
                type="file"
                accept=".csv,.xls,.xlsx"
                className="hidden"
                onChange={(event) => {
                  const file = event.target.files?.[0] ?? null;
                  setValue("product_sheet", file, { shouldDirty: true, shouldTouch: true });
                }}
              />
              {savedDocuments.product_sheet && !productSheet ? (
                <a
                  href={savedDocuments.product_sheet}
                  target="_blank"
                  rel="noopener noreferrer"
                  className="mt-2 inline-block text-xs font-medium text-[#CC1414] hover:underline"
                >
                  View uploaded sheet
                </a>
              ) : null}
            </div>
          )}
        </div>
      </div>
    </div>
  );
}
