"use client";

import { useState } from "react";
import { AVERY_SPECS, type JarType } from "@/lib/avery-specs";
import { saveSheet } from "@/lib/actions/sheets";
import {
  LabelPickerModal,
  type PickerFolder,
  type PickerLabel,
} from "./LabelPickerModal";

type Slot = PickerLabel | null;
type Page = Slot[];

const JAR_TYPE_LABELS: Record<JarType, string> = {
  wide: `Wide Mouth (Avery ${AVERY_SPECS.wide.sku}, ${AVERY_SPECS.wide.diameterInches}")`,
  regular: `Regular Mouth (Avery ${AVERY_SPECS.regular.sku}, ${AVERY_SPECS.regular.diameterInches}")`,
};

function emptyPage(jarType: JarType): Page {
  return new Array(AVERY_SPECS[jarType].labelsPerSheet).fill(null);
}

export function SheetBuilderClient({
  folders,
  initialJarType,
  initialPages,
}: {
  folders: PickerFolder[];
  initialJarType: JarType;
  initialPages: Page[] | null;
}) {
  const [jarType, setJarType] = useState<JarType>(initialJarType);
  const [pages, setPages] = useState<Page[]>(
    initialPages && initialPages.length > 0 ? initialPages : [emptyPage(initialJarType)],
  );
  const [pickerTarget, setPickerTarget] = useState<{
    pageIndex: number;
    slotIndex: number;
  } | null>(null);
  const [isExporting, setIsExporting] = useState(false);
  const [isSaving, setIsSaving] = useState(false);
  const [saveMessage, setSaveMessage] = useState<string | null>(null);
  const [showSaveInput, setShowSaveInput] = useState(false);
  const [sheetName, setSheetName] = useState("");

  const spec = AVERY_SPECS[jarType];
  const columns = spec.columnCentersPt.length;

  function handleJarTypeChange(next: JarType) {
    if (next === jarType) return;
    const hasAnyFilled = pages.some((page) => page.some((slot) => slot !== null));
    if (hasAnyFilled && !confirm("Switching jar type clears your current sheet(s). Continue?")) {
      return;
    }
    setJarType(next);
    setPages([emptyPage(next)]);
  }

  function assignLabel(label: PickerLabel) {
    if (!pickerTarget) return;
    const { pageIndex, slotIndex } = pickerTarget;
    setPages((prev) =>
      prev.map((page, pIdx) =>
        pIdx !== pageIndex
          ? page
          : page.map((slot, sIdx) => (sIdx === slotIndex ? label : slot)),
      ),
    );
    setPickerTarget(null);
  }

  function clearSlot(pageIndex: number, slotIndex: number) {
    setPages((prev) =>
      prev.map((page, pIdx) =>
        pIdx !== pageIndex
          ? page
          : page.map((slot, sIdx) => (sIdx === slotIndex ? null : slot)),
      ),
    );
  }

  function fillRemainingWith(label: PickerLabel) {
    setPages((prev) =>
      prev.map((page) => page.map((slot) => (slot === null ? label : slot))),
    );
  }

  function addPage() {
    setPages((prev) => [...prev, emptyPage(jarType)]);
  }

  function removePage(pageIndex: number) {
    if (pages.length <= 1) return;
    if (
      pages[pageIndex].some((slot) => slot !== null) &&
      !confirm("Remove this sheet? Its filled slots will be lost.")
    ) {
      return;
    }
    setPages((prev) => prev.filter((_, i) => i !== pageIndex));
  }

  async function handleExport() {
    setIsExporting(true);
    try {
      const res = await fetch("/api/sheet-builder/export", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          jarType,
          pages: pages.map((page) => page.map((slot) => slot?.id ?? null)),
        }),
      });
      if (!res.ok) {
        alert("Couldn't generate the PDF. Please try again.");
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement("a");
      a.href = url;
      a.download = `cellar-labels-sheet-${jarType}.pdf`;
      a.click();
      URL.revokeObjectURL(url);
    } finally {
      setIsExporting(false);
    }
  }

  async function handleSave() {
    const name = sheetName.trim();
    if (!name) return;
    setIsSaving(true);
    setSaveMessage(null);
    try {
      await saveSheet(
        name,
        jarType,
        pages.map((page) => page.map((slot) => slot?.id ?? null)),
      );
      setSaveMessage("Saved to your profile.");
      setShowSaveInput(false);
      setSheetName("");
    } finally {
      setIsSaving(false);
    }
  }

  return (
    <div>
      <div className="flex flex-wrap items-center gap-3">
        <span className="text-sm font-medium text-charcoal">Jar type:</span>
        {(Object.keys(JAR_TYPE_LABELS) as JarType[]).map((type) => (
          <button
            key={type}
            type="button"
            onClick={() => handleJarTypeChange(type)}
            className={`rounded-full border px-4 py-1.5 text-sm font-medium ${
              jarType === type
                ? "border-terracotta bg-terracotta/10 text-terracotta"
                : "border-charcoal/20 text-charcoal hover:bg-charcoal/5"
            }`}
          >
            {JAR_TYPE_LABELS[type]}
          </button>
        ))}
      </div>

      <div className="mt-8 flex flex-col gap-10">
        {pages.map((page, pageIndex) => (
          <div key={pageIndex}>
            <div className="mb-3 flex items-center justify-between">
              <h2 className="font-heading text-lg font-semibold text-charcoal">
                Sheet {pageIndex + 1}
              </h2>
              {pages.length > 1 && (
                <button
                  type="button"
                  onClick={() => removePage(pageIndex)}
                  className="text-sm text-charcoal/60 hover:text-terracotta hover:underline"
                >
                  Remove sheet
                </button>
              )}
            </div>
            <div
              className="grid gap-4 rounded-lg border border-charcoal/10 bg-warm-white p-6"
              style={{ gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` }}
            >
              {page.map((slot, slotIndex) => (
                <div key={slotIndex} className="flex flex-col items-center gap-2">
                  {slot ? (
                    <>
                      {/* eslint-disable-next-line @next/next/no-img-element */}
                      <img
                        src={slot.fileUrl}
                        alt={`${slot.brandName} ${slot.blendName}`}
                        className="aspect-square w-full rounded-full border border-charcoal/10 object-cover"
                      />
                      <p className="text-center text-xs text-charcoal/70">
                        {slot.brandName} - {slot.blendName}
                      </p>
                      <div className="flex gap-2 text-xs">
                        <button
                          type="button"
                          onClick={() => clearSlot(pageIndex, slotIndex)}
                          className="text-charcoal/60 hover:text-terracotta hover:underline"
                        >
                          Remove
                        </button>
                        <button
                          type="button"
                          onClick={() => fillRemainingWith(slot)}
                          className="text-terracotta hover:underline"
                        >
                          Fill remaining
                        </button>
                      </div>
                    </>
                  ) : (
                    <button
                      type="button"
                      onClick={() => setPickerTarget({ pageIndex, slotIndex })}
                      className="flex aspect-square w-full items-center justify-center rounded-full border-2 border-dashed border-charcoal/20 text-2xl text-charcoal/30 hover:border-terracotta hover:text-terracotta"
                    >
                      +
                    </button>
                  )}
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>

      <div className="mt-6 flex flex-wrap gap-3">
        <button
          type="button"
          onClick={addPage}
          className="rounded-full border border-charcoal/20 px-5 py-2 text-sm font-medium text-charcoal hover:bg-charcoal/5"
        >
          + Add Sheet
        </button>
        <button
          type="button"
          onClick={handleExport}
          disabled={isExporting}
          className="rounded-full bg-terracotta px-5 py-2 text-sm font-medium text-white hover:bg-terracotta/90 disabled:opacity-60"
        >
          {isExporting ? "Generating PDF..." : "Download PDF"}
        </button>
        {showSaveInput ? (
          <div className="flex items-center gap-2">
            <input
              type="text"
              value={sheetName}
              onChange={(e) => setSheetName(e.target.value)}
              placeholder="Name this sheet"
              autoFocus
              className="rounded-full border border-charcoal/20 bg-warm-white px-4 py-2 text-sm text-charcoal focus:border-terracotta focus:outline-none"
            />
            <button
              type="button"
              onClick={handleSave}
              disabled={isSaving || !sheetName.trim()}
              className="rounded-full bg-terracotta px-5 py-2 text-sm font-medium text-white hover:bg-terracotta/90 disabled:opacity-60"
            >
              {isSaving ? "Saving..." : "Save"}
            </button>
            <button
              type="button"
              onClick={() => {
                setShowSaveInput(false);
                setSheetName("");
              }}
              className="text-sm text-charcoal/60 hover:underline"
            >
              Cancel
            </button>
          </div>
        ) : (
          <button
            type="button"
            onClick={() => setShowSaveInput(true)}
            className="rounded-full border border-charcoal/20 px-5 py-2 text-sm font-medium text-charcoal hover:bg-charcoal/5"
          >
            Save Sheet
          </button>
        )}
        {saveMessage && (
          <span className="self-center text-sm text-charcoal/60">{saveMessage}</span>
        )}
      </div>

      <LabelPickerModal
        open={pickerTarget !== null}
        onClose={() => setPickerTarget(null)}
        onSelect={assignLabel}
        folders={folders}
      />
    </div>
  );
}
