"use client";

import { useState } from "react";
import { FieldType } from "@capakraken/shared";
import type { FieldOption } from "@capakraken/shared";
import type { CatalogField } from "~/lib/blueprint-field-catalog.js";

// ---------------------------------------------------------------------------
// Type icons
// ---------------------------------------------------------------------------

const TYPE_ICONS: Record<FieldType, string> = {
  [FieldType.TEXT]: "Aa",
  [FieldType.TEXTAREA]: "Aa",
  [FieldType.NUMBER]: "#",
  [FieldType.BOOLEAN]: "\u2611",
  [FieldType.DATE]: "\u{1F4C5}",
  [FieldType.SELECT]: "\u25BC",
  [FieldType.MULTI_SELECT]: "\u25BC\u25BC",
  [FieldType.URL]: "\u{1F517}",
  [FieldType.EMAIL]: "@",
};

const TYPE_LABELS: Record<FieldType, string> = {
  [FieldType.TEXT]: "Text",
  [FieldType.TEXTAREA]: "Textarea",
  [FieldType.NUMBER]: "Number",
  [FieldType.BOOLEAN]: "Boolean",
  [FieldType.DATE]: "Date",
  [FieldType.SELECT]: "Select",
  [FieldType.MULTI_SELECT]: "Multi-Select",
  [FieldType.URL]: "URL",
  [FieldType.EMAIL]: "Email",
};

// ---------------------------------------------------------------------------
// Field overrides that the user can set per-field
// ---------------------------------------------------------------------------

export interface FieldOverrides {
  enabled: boolean;
  required: boolean;
  showInList: boolean;
  defaultValue: unknown;
  description: string;
}

// ---------------------------------------------------------------------------
// Props
// ---------------------------------------------------------------------------

interface FieldCardProps {
  field: CatalogField;
  overrides: FieldOverrides;
  onChange: (overrides: FieldOverrides) => void;
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

const INPUT_CLS =
  "px-3 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-500 text-sm";

export function FieldCard({ field, overrides, onChange }: FieldCardProps) {
  const [expanded, setExpanded] = useState(false);

  function update(patch: Partial<FieldOverrides>) {
    onChange({ ...overrides, ...patch });
  }

  function handleToggle() {
    const next = !overrides.enabled;
    update({ enabled: next });
    if (!next) {
      setExpanded(false);
    }
  }

  const isActive = overrides.enabled;

  return (
    <div
      className={`border rounded-lg transition-all ${
        isActive
          ? "border-brand-400/60 bg-brand-50/40 shadow-sm dark:border-brand-600/50 dark:bg-brand-950/50"
          : "border-gray-200 bg-white dark:border-gray-700/50 dark:bg-gray-800"
      }`}
    >
      {/* Header row */}
      <div
        className="flex items-center gap-3 px-4 py-3 cursor-pointer select-none"
        onClick={() => {
          if (isActive) setExpanded((v) => !v);
          else handleToggle();
        }}
      >
        {/* Type icon */}
        <span
          className={`w-8 h-8 rounded-md flex items-center justify-center text-sm font-bold shrink-0 ${
            isActive
              ? "bg-brand-100 text-brand-700 dark:bg-brand-900/50 dark:text-brand-300"
              : "bg-gray-100 text-gray-400 dark:bg-gray-700 dark:text-gray-500"
          }`}
          title={TYPE_LABELS[field.type]}
        >
          {TYPE_ICONS[field.type]}
        </span>

        {/* Label + description */}
        <div className="flex-1 min-w-0">
          <div className="flex items-center gap-2">
            <span
              className={`font-medium text-sm truncate ${
                isActive ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"
              }`}
            >
              {field.label}
            </span>
            <span className="text-xs text-gray-400 dark:text-gray-500 font-mono hidden sm:inline">
              {field.key}
            </span>
          </div>
          <p className="text-xs text-gray-400 dark:text-gray-500 truncate">{field.description}</p>
        </div>

        {/* Toggle switch */}
        <button
          type="button"
          role="switch"
          aria-checked={isActive}
          aria-label={`Toggle ${field.label}`}
          onClick={(e) => {
            e.stopPropagation();
            handleToggle();
          }}
          className={`relative inline-flex h-6 w-11 shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:ring-offset-2 ${
            isActive ? "bg-brand-600" : "bg-gray-300 dark:bg-gray-600"
          }`}
        >
          <span
            className={`inline-block h-5 w-5 rounded-full bg-white shadow-sm transform transition-transform duration-200 ${
              isActive ? "translate-x-5" : "translate-x-0"
            }`}
          />
        </button>
      </div>

      {/* Expanded settings */}
      {isActive && expanded && (
        <div className="px-4 pb-4 pt-1 border-t border-brand-200/50 space-y-3">
          {/* Default value input */}
          <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-gray-600 dark:text-gray-300">
              Default Value
            </label>
            <DefaultValueInput
              type={field.type}
              {...(field.options ? { options: field.options } : {})}
              value={overrides.defaultValue}
              onChange={(val) => update({ defaultValue: val })}
            />
          </div>

          {/* Toggles row */}
          <div className="flex flex-wrap items-center gap-4">
            <label className="flex items-center gap-1.5 text-sm text-gray-700 dark:text-gray-200 cursor-pointer select-none">
              <input
                type="checkbox"
                checked={overrides.required}
                onChange={(e) => update({ required: e.target.checked })}
                className="w-4 h-4 rounded border-gray-300 text-brand-600 focus:ring-brand-500"
              />
              Required
            </label>
            <label className="flex items-center gap-1.5 text-sm text-gray-700 dark:text-gray-200 cursor-pointer select-none">
              <input
                type="checkbox"
                checked={overrides.showInList}
                onChange={(e) => update({ showInList: e.target.checked })}
                className="w-4 h-4 rounded border-gray-300 text-brand-600 focus:ring-brand-500"
              />
              Show in list
            </label>
          </div>

          {/* Description override */}
          <div className="flex flex-col gap-1">
            <label className="text-xs font-medium text-gray-600 dark:text-gray-300">
              Helper Text
            </label>
            <input
              type="text"
              value={overrides.description}
              onChange={(e) => update({ description: e.target.value })}
              placeholder={field.description}
              className={INPUT_CLS}
            />
          </div>
        </div>
      )}
    </div>
  );
}

// ---------------------------------------------------------------------------
// Type-appropriate default value input
// ---------------------------------------------------------------------------

function DefaultValueInput({
  type,
  options,
  value,
  onChange,
}: {
  type: FieldType;
  options?: FieldOption[];
  value: unknown;
  onChange: (val: unknown) => void;
}) {
  switch (type) {
    case FieldType.BOOLEAN:
      return (
        <label className="flex items-center gap-2 text-sm text-gray-700 dark:text-gray-200 cursor-pointer select-none">
          <input
            type="checkbox"
            checked={Boolean(value)}
            onChange={(e) => onChange(e.target.checked)}
            className="w-4 h-4 rounded border-gray-300 text-brand-600 focus:ring-brand-500"
          />
          {value ? "True" : "False"}
        </label>
      );

    case FieldType.NUMBER:
      return (
        <input
          type="number"
          value={value != null ? String(value) : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : Number(e.target.value))
          }
          placeholder="No default"
          className={INPUT_CLS}
        />
      );

    case FieldType.DATE:
      return (
        <input
          type="date"
          value={typeof value === "string" ? value : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : e.target.value)
          }
          className={INPUT_CLS}
        />
      );

    case FieldType.SELECT:
      return (
        <select
          value={typeof value === "string" ? value : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : e.target.value)
          }
          className={INPUT_CLS}
        >
          <option value="">No default</option>
          {(options ?? []).map((opt) => (
            <option key={opt.value} value={opt.value}>
              {opt.label}
            </option>
          ))}
        </select>
      );

    case FieldType.MULTI_SELECT:
      return (
        <MultiSelectDefaultInput
          options={options ?? []}
          value={Array.isArray(value) ? (value as string[]) : []}
          onChange={onChange}
        />
      );

    case FieldType.URL:
      return (
        <input
          type="url"
          value={typeof value === "string" ? value : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : e.target.value)
          }
          placeholder="https://..."
          className={INPUT_CLS}
        />
      );

    case FieldType.EMAIL:
      return (
        <input
          type="email"
          value={typeof value === "string" ? value : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : e.target.value)
          }
          placeholder="name@example.com"
          className={INPUT_CLS}
        />
      );

    case FieldType.TEXTAREA:
      return (
        <textarea
          value={typeof value === "string" ? value : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : e.target.value)
          }
          placeholder="No default"
          className={`${INPUT_CLS} resize-none`}
          rows={2}
        />
      );

    default:
      return (
        <input
          type="text"
          value={typeof value === "string" ? value : ""}
          onChange={(e) =>
            onChange(e.target.value === "" ? undefined : e.target.value)
          }
          placeholder="No default"
          className={INPUT_CLS}
        />
      );
  }
}

// ---------------------------------------------------------------------------
// Multi-select checkboxes for default value
// ---------------------------------------------------------------------------

function MultiSelectDefaultInput({
  options,
  value,
  onChange,
}: {
  options: FieldOption[];
  value: string[];
  onChange: (val: string[]) => void;
}) {
  function toggleOption(optValue: string) {
    const next = value.includes(optValue)
      ? value.filter((v) => v !== optValue)
      : [...value, optValue];
    onChange(next.length > 0 ? next : []);
  }

  if (options.length === 0) {
    return <span className="text-xs text-gray-400">No options defined</span>;
  }

  return (
    <div className="flex flex-wrap gap-2">
      {options.map((opt) => (
        <label
          key={opt.value}
          className="flex items-center gap-1.5 text-sm text-gray-700 dark:text-gray-200 cursor-pointer select-none"
        >
          <input
            type="checkbox"
            checked={value.includes(opt.value)}
            onChange={() => toggleOption(opt.value)}
            className="w-3.5 h-3.5 rounded border-gray-300 text-brand-600 focus:ring-brand-500"
          />
          {opt.label}
        </label>
      ))}
    </div>
  );
}
