import { useMemo, useRef, useState } from "react";
import type {
  BuilderFormData,
  SiteBuilderMetadata,
  StylePreferences,
} from "../../../../types/siteBuilder";
import { Card } from "../../../../components/ui/card";
import { Dropdown } from "../../../../components/ui/dropdown/Dropdown";
import { CheckLineIcon } from "../../../../icons";

const labelClass =
  "text-sm font-semibold text-gray-700 dark:text-white/80 mb-2 inline-block";
const selectClass =
  "h-11 w-full rounded-xl border border-gray-200 bg-white px-4 text-sm font-medium text-gray-900 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-white/10 dark:bg-white/[0.03] dark:text-white/90 dark:focus:border-brand-800";
const inputClass =
  "h-11 w-full rounded-xl border border-gray-200 bg-white px-4 text-sm font-medium text-gray-900 placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-white/10 dark:bg-white/[0.03] dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800";
const textareaClass =
  "w-full rounded-2xl border border-gray-200 bg-white px-4 py-3 text-sm font-medium text-gray-900 placeholder:text-gray-400 focus:border-brand-300 focus:outline-hidden focus:ring-3 focus:ring-brand-500/10 dark:border-white/10 dark:bg-white/[0.03] dark:text-white/90 dark:placeholder:text-white/30 dark:focus:border-brand-800";

const palettes = [
  "Minimal monochrome with bright accent",
  "Rich jewel tones with high contrast",
  "Soft gradients and glassmorphism",
  "Playful pastel palette",
];

const typography = [
  "Modern sans-serif for headings, serif body text",
  "Editorial serif across the site",
  "Geometric sans with tight tracking",
  "Rounded fonts with friendly tone",
];

interface Props {
  style: StylePreferences;
  metadata?: SiteBuilderMetadata;
  brandPersonalityIds: number[];
  customBrandPersonality?: string;
  heroImageryDirectionId: number | null;
  customHeroImageryDirection?: string;
  onStyleChange: (partial: Partial<StylePreferences>) => void;
  onChange: <K extends keyof BuilderFormData>(
    key: K,
    value: BuilderFormData[K],
  ) => void;
}

export function StyleStep({
  style,
  metadata,
  brandPersonalityIds,
  customBrandPersonality,
  heroImageryDirectionId,
  customHeroImageryDirection,
  onStyleChange,
  onChange,
}: Props) {
  const brandOptions = metadata?.brand_personalities ?? [];
  const heroOptions = metadata?.hero_imagery_directions ?? [];

  const [heroDropdownOpen, setHeroDropdownOpen] = useState(false);
  const heroButtonRef = useRef<HTMLButtonElement>(null);
  const [brandDropdownOpen, setBrandDropdownOpen] = useState(false);
  const brandButtonRef = useRef<HTMLButtonElement>(null);

  const selectedBrandOptions = useMemo(
    () => brandOptions.filter((option) => brandPersonalityIds.includes(option.id)),
    [brandOptions, brandPersonalityIds],
  );

  const selectedHero = heroOptions.find(
    (option) => option.id === heroImageryDirectionId,
  );

  const toggleBrand = (id: number) => {
    const isSelected = brandPersonalityIds.includes(id);
    const next = isSelected
      ? brandPersonalityIds.filter((value) => value !== id)
      : [...brandPersonalityIds, id];
    onChange("brandPersonalityIds", next);
  };

  return (
    <Card variant="surface" padding="lg">
      <div className="space-y-6">
        <div>
          <p className="text-xs uppercase tracking-wider text-gray-500 dark:text-white/50">
            Look &amp; feel
          </p>
          <h3 className="text-lg font-semibold text-gray-900 dark:text-white">
            Visual direction
          </h3>
          <p className="text-sm text-gray-500 dark:text-gray-400">
            Capture the brand personality so the preview canvas mirrors the right tone.
          </p>
        </div>

        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          <div>
            <label className={labelClass}>Palette direction</label>
            <select
              className={selectClass}
              value={style.palette}
              onChange={(event) => onStyleChange({ palette: event.target.value })}
            >
              {palettes.map((option) => (
                <option key={option} value={option}>
                  {option}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label className={labelClass}>Typography</label>
            <select
              className={selectClass}
              value={style.typography}
              onChange={(event) =>
                onStyleChange({ typography: event.target.value })
              }
            >
              {typography.map((option) => (
                <option key={option} value={option}>
                  {option}
                </option>
              ))}
            </select>
          </div>
        </div>

        <div className="space-y-4">
          <div>
            <label className={labelClass}>Brand personality profiles</label>
            <p className="text-xs text-gray-500 dark:text-gray-400">
              Select up to three descriptors that define the brand tone.
            </p>
          </div>
          <div>
            <button
              ref={brandButtonRef}
              type="button"
              onClick={() => setBrandDropdownOpen((open) => !open)}
              className="dropdown-toggle flex w-full items-center justify-between rounded-xl border border-gray-200 bg-white px-4 py-3 text-sm font-medium text-gray-900 transition hover:border-brand-200 dark:border-white/10 dark:bg-white/[0.02] dark:text-white/90"
            >
              <span>
                {brandPersonalityIds.length > 0
                  ? `${brandPersonalityIds.length} personality${
                      brandPersonalityIds.length > 1 ? " descriptors" : " descriptor"
                    } selected`
                  : "Choose personalities from the IGNY8 library"}
              </span>
              <svg
                className="h-4 w-4 text-gray-500 dark:text-gray-400"
                viewBox="0 0 20 20"
                fill="currentColor"
              >
                <path
                  fillRule="evenodd"
                  d="M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.08 1.04l-4.25 4.25a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z"
                  clipRule="evenodd"
                />
              </svg>
            </button>
            <Dropdown
              isOpen={brandDropdownOpen}
              onClose={() => setBrandDropdownOpen(false)}
              anchorRef={brandButtonRef}
              placement="bottom-left"
              className="w-80 max-h-80 overflow-y-auto p-2"
            >
              {brandOptions.length === 0 ? (
                <div className="px-3 py-2 text-sm text-gray-500">
                  No brand personalities defined yet. Use the custom field below.
                </div>
              ) : (
                brandOptions.map((option) => {
                  const isSelected = brandPersonalityIds.includes(option.id);
                  const disabled =
                    !isSelected && brandPersonalityIds.length >= 3;
                  return (
                    <button
                      key={option.id}
                      type="button"
                      disabled={disabled}
                      onClick={() => toggleBrand(option.id)}
                      className={`flex w-full items-start gap-3 rounded-xl px-3 py-2 text-left text-sm ${
                        isSelected
                          ? "bg-brand-50 text-brand-700 dark:bg-brand-500/10 dark:text-brand-100"
                          : "text-gray-700 hover:bg-gray-100 disabled:opacity-50 dark:text-white/80 dark:hover:bg-white/10"
                      }`}
                    >
                      <span className="flex-1">
                        <span className="font-semibold">{option.name}</span>
                        {option.description && (
                          <span className="block text-xs text-gray-500 dark:text-gray-400">
                            {option.description}
                          </span>
                        )}
                      </span>
                      {isSelected && <CheckLineIcon className="h-4 w-4" />}
                    </button>
                  );
                })
              )}
            </Dropdown>
          </div>
          <div className="flex flex-wrap gap-2">
            {selectedBrandOptions.map((option) => (
              <span
                key={option.id}
                className="inline-flex items-center gap-2 rounded-full bg-brand-50 px-3 py-1 text-xs font-semibold text-brand-700 dark:bg-brand-500/10 dark:text-brand-100"
              >
                {option.name}
                <button
                  type="button"
                  className="text-brand-600 hover:text-brand-800 dark:text-brand-100 dark:hover:text-brand-50"
                  onClick={() => toggleBrand(option.id)}
                  aria-label={`Remove ${option.name}`}
                >
                  ×
                </button>
              </span>
            ))}
            {customBrandPersonality?.trim() && (
              <span className="inline-flex items-center rounded-full bg-gray-100 px-3 py-1 text-xs font-semibold text-gray-700 dark:bg-white/10 dark:text-white/80">
                {customBrandPersonality.trim()}
              </span>
            )}
          </div>
          <input
            className={inputClass}
            type="text"
            value={customBrandPersonality ?? ""}
            placeholder="Add custom personality descriptor"
            onChange={(event) =>
              onChange("customBrandPersonality", event.target.value)
            }
          />
        </div>

        <div className="grid grid-cols-1 gap-6 md:grid-cols-2">
          <div>
            <label className={labelClass}>Brand personality narrative</label>
            <textarea
              className={textareaClass}
              rows={4}
              value={style.personality}
              onChange={(event) =>
                onStyleChange({ personality: event.target.value })
              }
            />
          </div>
          <div>
            <label className={labelClass}>Hero imagery direction</label>
            <button
              ref={heroButtonRef}
              type="button"
              onClick={() => setHeroDropdownOpen((open) => !open)}
              className="dropdown-toggle flex w-full items-center justify-between rounded-xl border border-gray-200 bg-white px-4 py-3 text-sm font-medium text-gray-900 transition hover:border-brand-200 dark:border-white/10 dark:bg-white/[0.02] dark:text-white/90"
            >
              <span>
                {selectedHero?.name ||
                  "Select a hero imagery direction from the library"}
              </span>
              <svg
                className="h-4 w-4 text-gray-500 dark:text-gray-400"
                viewBox="0 0 20 20"
                fill="currentColor"
              >
                <path
                  fillRule="evenodd"
                  d="M5.23 7.21a.75.75 0 011.06.02L10 10.94l3.71-3.71a.75.75 0 111.08 1.04l-4.25 4.25a.75.75 0 01-1.08 0L5.21 8.27a.75.75 0 01.02-1.06z"
                  clipRule="evenodd"
                />
              </svg>
            </button>
            <Dropdown
              isOpen={heroDropdownOpen}
              onClose={() => setHeroDropdownOpen(false)}
              anchorRef={heroButtonRef}
              placement="bottom-left"
              className="w-80 max-h-72 overflow-y-auto p-2"
            >
              {heroOptions.length === 0 ? (
                <div className="px-3 py-2 text-sm text-gray-500">
                  No hero imagery directions defined yet.
                </div>
              ) : (
                heroOptions.map((option) => {
                  const isSelected = option.id === heroImageryDirectionId;
                  return (
                    <button
                      key={option.id}
                      type="button"
                      onClick={() => {
                        onChange("heroImageryDirectionId", option.id);
                        onChange("customHeroImageryDirection", "");
                        onStyleChange({ heroImagery: option.name });
                        setHeroDropdownOpen(false);
                      }}
                      className={`flex w-full items-start gap-3 rounded-xl px-3 py-2 text-left text-sm ${
                        isSelected
                          ? "bg-brand-50 text-brand-700 dark:bg-brand-500/10 dark:text-brand-100"
                          : "text-gray-700 hover:bg-gray-100 dark:text-white/80 dark:hover:bg-white/10"
                      }`}
                    >
                      <span className="flex-1">
                        <span className="font-semibold">{option.name}</span>
                        {option.description && (
                          <span className="block text-xs text-gray-500 dark:text-gray-400">
                            {option.description}
                          </span>
                        )}
                      </span>
                      {isSelected && <CheckLineIcon className="h-4 w-4" />}
                    </button>
                  );
                })
              )}
            </Dropdown>
            <input
              className={`${inputClass} mt-3`}
              type="text"
              value={customHeroImageryDirection ?? ""}
              placeholder="Or describe a custom hero imagery direction"
              onChange={(event) => {
                onChange("customHeroImageryDirection", event.target.value);
                onChange("heroImageryDirectionId", null);
              }}
            />
            <textarea
              className={`${textareaClass} mt-3`}
              rows={4}
              value={style.heroImagery}
              onChange={(event) =>
                onStyleChange({ heroImagery: event.target.value })
              }
            />
          </div>
        </div>
      </div>
    </Card>
  );
}

