import { useState } from "react";
import type { UiHint, UiHintField } from "../types";

type Props = {
  uiHint: UiHint | null;
  candidates?: string[];
  availableJourneys?: string[];
  onSubmit(text: string): void;
};

/**
 * SmartControl renders the right interactive widget under the latest assistant bubble
 * based on the agent's ui_hint. We always offer the text composer below, so this is
 * a *shortcut* for the user, not a forced channel.
 *
 *   - multi_slot_form -> full form with dropdowns / number / date inputs
 *   - dropdown        -> chip grid of vocabulary values
 *   - date            -> native date input
 *   - confirm         -> Yes / Not yet
 *   - candidates      -> journey-choice cards (ambiguity)
 *   - text            -> nothing (composer handles it)
 */
export function SmartControl({ uiHint, candidates = [], availableJourneys = [], onSubmit }: Props) {
  // Ambiguity / journey-choice always wins if present.
  if (candidates.length > 0) {
    return (
      <div className="smart-control">
        <div className="smart-label">Which would you like?</div>
        <div className="option-grid">
          {candidates.map((c) => {
            const available = availableJourneys.includes(c);
            return (
              <button
                key={c}
                className="option-chip option-chip--journey"
                onClick={() => onSubmit(c)}
                title={available ? "Click to choose" : "Recognised, but not yet implemented"}
              >
                <small>{available ? "available" : "coming soon"}</small>
                <span>{c}</span>
              </button>
            );
          })}
        </div>
      </div>
    );
  }

  if (!uiHint || uiHint.kind === "text") return null;

  if (uiHint.kind === "multi_slot_form" && uiHint.fields && uiHint.fields.length > 0) {
    return <MultiSlotForm uiHint={uiHint} onSubmit={onSubmit} />;
  }

  if (uiHint.kind === "dropdown" && uiHint.options && uiHint.options.length > 0) {
    return (
      <div className="smart-control">
        <div className="smart-label">
          {uiHint.label || uiHint.slot || "Pick one"}
        </div>
        <div className="option-grid">
          {uiHint.options.map((opt) => (
            <button key={opt} className="option-chip" onClick={() => onSubmit(prettify(opt))}>
              {humanLabelForOption(uiHint.slot, opt)}
            </button>
          ))}
        </div>
      </div>
    );
  }

  if (uiHint.kind === "date") {
    return <DateControl uiHint={uiHint} onSubmit={onSubmit} />;
  }

  if (uiHint.kind === "confirm") {
    return (
      <div className="smart-control">
        <div className="option-grid">
          <button className="option-chip" onClick={() => onSubmit("yes, go ahead")}>
            Yes, create it
          </button>
          <button className="option-chip" onClick={() => onSubmit("not yet")}>
            Not yet
          </button>
        </div>
      </div>
    );
  }

  return null;
}

function DateControl({ uiHint, onSubmit }: { uiHint: UiHint; onSubmit(text: string): void }) {
  const label = uiHint.label || uiHint.slot || "Pick a date";
  return (
    <div className="smart-control">
      <div className="smart-label">{label}</div>
      <input
        type="date"
        className="option-chip"
        style={{ width: 200 }}
        onChange={(e) => {
          if (e.target.value) onSubmit(e.target.value);
        }}
      />
    </div>
  );
}

// ============================================================================
// Multi-slot form — beautiful in-theme card with dropdowns / number / date
// ============================================================================

function MultiSlotForm({ uiHint, onSubmit }: { uiHint: UiHint; onSubmit(text: string): void }) {
  const fields = uiHint.fields ?? [];
  const [values, setValues] = useState<Record<string, string>>({});
  const filledCount = Object.values(values).filter((v) => v && v.trim()).length;

  function buildMessage(): string {
    // Compose a natural-sounding sentence the slot extractor can parse. We use a templated
    // phrasing that maps slot → English fragment (the labels come from the form fields).
    const parts: string[] = [];
    for (const f of fields) {
      const v = (values[f.slot] || "").trim();
      if (!v) continue;
      parts.push(`${f.label} ${v}`);
    }
    return parts.join(", ") + ".";
  }

  function handleSubmit() {
    if (filledCount === 0) return;
    onSubmit(buildMessage());
  }

  return (
    <div className="msf">
      {uiHint.title && <div className="msf__title">{uiHint.title}</div>}
      <div className="msf__hint">
        Fill in what you can — leave the rest blank. You can also just type your answer in
        the chat box below if you prefer.
      </div>
      <div className="msf__grid">
        {fields.map((f) => (
          <MsfField
            key={f.slot}
            field={f}
            value={values[f.slot] || ""}
            onChange={(v) => setValues((s) => ({ ...s, [f.slot]: v }))}
          />
        ))}
      </div>
      <div className="msf__actions">
        <span className="msf__counter">
          {filledCount > 0 ? `${filledCount} field${filledCount === 1 ? "" : "s"} filled` : "No fields filled yet"}
        </span>
        <button
          className="msf__submit"
          onClick={handleSubmit}
          disabled={filledCount === 0}
        >
          Submit
        </button>
      </div>
    </div>
  );
}

function MsfField({
  field, value, onChange,
}: { field: UiHintField; value: string; onChange(v: string): void }) {
  return (
    <label className="msf__field">
      <span className="msf__label">{field.label}</span>
      {field.kind === "dropdown" ? (
        <select
          className="msf__input msf__input--select"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        >
          <option value="">— select —</option>
          {(field.options || []).map((o) => (
            <option key={o} value={o}>{o}</option>
          ))}
        </select>
      ) : field.kind === "date" ? (
        <input
          className="msf__input"
          type="date"
          value={value}
          onChange={(e) => onChange(e.target.value)}
        />
      ) : field.kind === "number" ? (
        <input
          className="msf__input"
          type="number"
          inputMode="numeric"
          step="any"
          value={value}
          placeholder={field.placeholder || ""}
          onChange={(e) => onChange(e.target.value)}
        />
      ) : (
        <input
          className="msf__input"
          type="text"
          value={value}
          placeholder={field.placeholder || ""}
          onChange={(e) => onChange(e.target.value)}
        />
      )}
    </label>
  );
}

// Render a friendly label for known coded slots. potypeenum 1/2/3/4 -> General/Capital/Dropship/Consignment.
function humanLabelForOption(slot: string | undefined, opt: string): string {
  if (!slot) return opt;
  if (slot.toLowerCase() === "potypeenum") {
    const m: Record<string, string> = { "1": "General", "2": "Capital", "3": "Dropship", "4": "Consignment" };
    return m[opt] ? `${m[opt]}` : opt;
  }
  return opt;
}

function prettify(s: string): string { return s; }
