import { useEffect } from "react";
import { Plus, Trash2 } from "lucide-react";
import { useFieldArray, type UseFormReturn } from "react-hook-form";
import type { ApiBrand, ApiPackagingType } from "@/lib/api/types";
import { type ProductFormValues } from "./product.schema";
import { ErrorText, Field, SectionCard, inputClass } from "./fields";

type Props = {
  form: UseFormReturn<ProductFormValues>;
  brands: ApiBrand[];
  packagingTypes: ApiPackagingType[];
  /**
   * Editing an existing product: the grade list is fixed and only the ticks and
   * prices are the seller's to change. New grades belong to the parent catalog
   * product, not to one seller's copy of it.
   */
  locked: boolean;
  /**
   * On a catalog-linked product, the brands that product is actually stocked
   * under. Null when the seller's product is their own, in which case the full
   * brand list applies.
   */
  catalogBrands?: Array<{ id: number; name: string }> | null;
};

export default function Step3QualityBrand({
  form,
  brands,
  packagingTypes,
  locked,
  catalogBrands = null,
}: Props) {
  const {
    register,
    control,
    watch,
    setValue,
    getValues,
    formState: { errors },
  } = form;

  const qualities = useFieldArray({ control, name: "qualities" });
  const packaging = useFieldArray({ control, name: "packaging" });
  const qualityDescLen = (watch("quality_description") || "").length;
  const selectedQualities = watch("qualities");
  const chosenPackaging = watch("packaging");
  const brandId = watch("brand_id");

  /*
    Re-apply the saved brand once its options exist — `register` seeds a <select>
    on mount, and a value matching no option falls back to blank. Same guard the
    category dropdown needs on the edit screen.
  */
  useEffect(() => {
    const saved = getValues("brand_id");
    if (saved && brands.some((brand) => String(brand.id) === saved)) {
      setValue("brand_id", saved);
    }
  }, [brands, getValues, setValue]);

  /*
    A linked product may only be offered under a brand the catalog stocks it in:
    a brand with no state and no price behind it has nothing for the platform to
    quote. An empty catalog list means the catalog never recorded any, so the
    full list is better than an empty dropdown.
  */
  const brandOptions =
    catalogBrands && catalogBrands.length
      ? catalogBrands.map((brand) => ({ id: brand.id, name: brand.name }))
      : brands.map((brand) => ({ id: brand.id, name: brand.name }));
  const brandsAreNarrowed = Boolean(catalogBrands && catalogBrands.length);

  /** Being in the `packaging` array is the selection, so ticking adds a row. */
  const packagingIndexOf = (typeId: number) =>
    (chosenPackaging ?? []).findIndex((row) => String(row.type) === String(typeId));

  const togglePackaging = (typeId: number, on: boolean) => {
    const index = packagingIndexOf(typeId);
    if (on && index === -1) packaging.append({ type: String(typeId), charge: "" });
    if (!on && index !== -1) packaging.remove(index);
  };

  const qualityListError = errors.qualities?.message ?? errors.qualities?.root?.message;

  return (
    <div className="space-y-4">
      <SectionCard
        title="Quality & Quality Charges"
        subtitle={
          locked
            ? "Tick the grades you sell and set the price difference on each."
            : "List the grades you sell and the price difference on each."
        }
      >
        <div className="overflow-x-auto">
          <table className="w-full min-w-[520px] border-collapse text-sm">
            <thead>
              <tr className="border-b border-gray-200 text-left text-xs font-medium text-gray-600">
                <th className="w-16 pb-2 pr-3">Sell</th>
                <th className="pb-2 pr-3">Quality</th>
                <th className="pb-2 pr-3">Price Difference (₹)</th>
                {locked ? null : <th className="pb-2 text-right">Action</th>}
              </tr>
            </thead>
            <tbody>
              {qualities.fields.map((field, index) => {
                const selected = selectedQualities?.[index]?.selected ?? false;
                return (
                  <tr key={field.id} className="border-b border-gray-100 align-top">
                    <td className="py-2 pr-3">
                      <input
                        type="checkbox"
                        {...register(`qualities.${index}.selected`)}
                        className="mt-2 h-4 w-4 accent-[#CC1414]"
                        aria-label={`Sell ${selectedQualities?.[index]?.name || `grade ${index + 1}`}`}
                      />
                    </td>
                    <td className="py-2 pr-3">
                      {locked ? (
                        <span className="inline-block py-2 font-medium text-gray-900">
                          {selectedQualities?.[index]?.name}
                        </span>
                      ) : (
                        <input
                          {...register(`qualities.${index}.name`)}
                          className={inputClass}
                          placeholder="e.g. Fe 500"
                        />
                      )}
                      <ErrorText message={errors.qualities?.[index]?.name?.message} />
                    </td>
                    <td className="py-2 pr-3">
                      {selected ? (
                        <input
                          {...register(`qualities.${index}.price`)}
                          className={inputClass}
                          placeholder="Enter price"
                          inputMode="decimal"
                        />
                      ) : (
                        <span className="inline-block py-2 text-xs text-gray-400">Not Applicable</span>
                      )}
                    </td>
                    {locked ? null : (
                      <td className="py-2 text-right">
                        <button
                          type="button"
                          onClick={() => qualities.remove(index)}
                          disabled={qualities.fields.length === 1}
                          className="rounded-md p-2 text-[#CC1414] hover:bg-rose-50 disabled:cursor-not-allowed disabled:opacity-40"
                          aria-label="Remove quality"
                        >
                          <Trash2 className="h-4 w-4" />
                        </button>
                      </td>
                    )}
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        <ErrorText message={qualityListError} />

        {locked ? (
          <p className="mt-3 text-xs text-gray-500">
            Grades come from the parent product, so buyers comparing sellers compare the same thing.
            Ask an admin to add one that is missing.
          </p>
        ) : (
          <button
            type="button"
            onClick={() => qualities.append({ name: "", price: "", selected: true })}
            className="mt-3 inline-flex items-center gap-1.5 rounded-lg border border-[#CC1414] px-3 py-1.5 text-sm font-medium text-[#CC1414] hover:bg-rose-50"
          >
            <Plus className="h-4 w-4" /> Add Quality
          </button>
        )}

        <div className="mt-4 grid grid-cols-1 gap-4 md:grid-cols-2">
          <Field label="Quality Inspection Charge (₹)" error={errors.quality_charge?.message}>
            <input
              {...register("quality_charge")}
              className={inputClass}
              placeholder="Enter inspection charge"
              inputMode="decimal"
            />
          </Field>

          <Field label="Quality Description" error={errors.quality_description?.message}>
            <div className="relative">
              <textarea
                {...register("quality_description")}
                rows={3}
                maxLength={300}
                className={inputClass}
                placeholder="Enter quality description"
              />
              <span className="pointer-events-none absolute bottom-2 right-3 text-[11px] text-gray-400">
                {qualityDescLen}/300
              </span>
            </div>
          </Field>
        </div>
      </SectionCard>

      <SectionCard
        title="Packaging Type & Charges"
        subtitle="Tick the packaging you can supply and add its charge."
      >
        {packagingTypes.length === 0 ? (
          <p className="text-sm text-gray-500">No packaging types are configured yet.</p>
        ) : (
          <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
            {packagingTypes.map((type) => {
              const index = packagingIndexOf(type.id);
              const selected = index !== -1;

              return (
                <div
                  key={type.id}
                  className={`rounded-lg border p-3 ${selected ? "border-[#CC1414] bg-rose-50/40" : "border-gray-200"}`}
                >
                  <label className="flex items-center gap-2 text-sm font-medium text-gray-800">
                    <input
                      type="checkbox"
                      checked={selected}
                      onChange={(e) => togglePackaging(type.id, e.target.checked)}
                      className="h-4 w-4 accent-[#CC1414]"
                    />
                    {type.name}
                  </label>

                  {selected ? (
                    <input
                      {...register(`packaging.${index}.charge`)}
                      className={`${inputClass} mt-2`}
                      placeholder="Charge (₹)"
                      inputMode="decimal"
                    />
                  ) : null}
                </div>
              );
            })}
          </div>
        )}
        <p className="mt-3 text-xs text-gray-500">
          Packaging types are managed by Biznie — pick from the list above.
        </p>
      </SectionCard>

      <SectionCard title="Brand & Make">
        <div className="grid grid-cols-1 gap-4 md:grid-cols-2">
          <Field label="Brand" error={errors.brand_id?.message}>
            <select {...register("brand_id")} className={inputClass}>
              <option value="">Select brand</option>
              {brandOptions.map((brand) => (
                <option key={brand.id} value={String(brand.id)}>
                  {brand.name}
                </option>
              ))}
            </select>
            {brandId && brandOptions.length > 0 && !brandOptions.some((brand) => String(brand.id) === brandId) ? (
              <p className="mt-1 text-xs text-amber-600">
                {brandsAreNarrowed
                  ? "The saved brand is not one this catalog product is stocked under — pick another one."
                  : "The saved brand is no longer available — pick another one."}
              </p>
            ) : null}
            {brandsAreNarrowed ? (
              <p className="mt-1 text-xs text-gray-500">
                Only the brands this catalog product is stocked under are listed.
              </p>
            ) : null}
          </Field>
          <Field label="Make" error={errors.make?.message}>
            <input {...register("make")} className={inputClass} placeholder="Enter make name" />
          </Field>
        </div>
      </SectionCard>
    </div>
  );
}
