import { ArrowLeft, Loader2, Play } from 'lucide-react';
import { useEffect, useMemo, useState } from 'react';

import type { BarkBattleConfigEditorPayload } from '../../../packages/shared/src/contracts/barkBattle';
import type { BarkBattleDifficultyPreset } from '../../../packages/shared/src/contracts/barkBattle';
import { buildBarkBattleDefaultOnomatopoeia } from '../../games/bark-battle/application/BarkBattleConfig';
import { BarkBattlePreviewCard } from './BarkBattlePreviewCard';

export type BarkBattleConfigEditorProps = {
  isBusy?: boolean;
  error?: string | null;
  onPreview: (payload: BarkBattleConfigEditorPayload) => void | Promise<void>;
  onBack?: () => void;
  showBackButton?: boolean;
  title?: string | null;
};

const DIFFICULTY_OPTIONS: Array<{ value: BarkBattleDifficultyPreset; label: string }> = [
  { value: 'easy', label: '轻松' },
  { value: 'normal', label: '标准' },
  { value: 'hard', label: '硬核' },
];
const FIELD_LABEL_CLASS =
  'mb-2 inline-flex rounded-full px-2 py-0.5 text-sm font-black text-[var(--platform-text-strong)]';
const ACCENT_FIELD_LABEL_CLASS =
  'mb-2 inline-flex rounded-full border border-rose-200/70 bg-rose-50/88 px-2.5 py-1 text-sm font-black text-rose-700 shadow-sm';
const DEFAULT_THEME_DESCRIPTION = '阳光草坪上的圆形声浪擂台';
const DEFAULT_PLAYER_IMAGE_DESCRIPTION = '戴红色围巾的勇敢小狗';
const DEFAULT_OPPONENT_IMAGE_DESCRIPTION = '戴蓝色头带的活力小狗';

function buildDefaultOnomatopoeiaText(params: {
  themeDescription: string;
  playerImageDescription: string;
  opponentImageDescription: string;
}) {
  return buildBarkBattleDefaultOnomatopoeia(params).join('\n');
}

export function BarkBattleConfigEditor({
  isBusy = false,
  error: externalError = null,
  onPreview,
  onBack,
  showBackButton = true,
  title: headingTitle = '汪汪声浪大作战',
}: BarkBattleConfigEditorProps) {
  const [title, setTitle] = useState('我的声浪竞技场');
  const [description, setDescription] = useState('');
  const [themeDescription, setThemeDescription] = useState(
    DEFAULT_THEME_DESCRIPTION,
  );
  const [playerImageDescription, setPlayerImageDescription] = useState(
    DEFAULT_PLAYER_IMAGE_DESCRIPTION,
  );
  const [opponentImageDescription, setOpponentImageDescription] = useState(
    DEFAULT_OPPONENT_IMAGE_DESCRIPTION,
  );
  const [isOnomatopoeiaCustomized, setIsOnomatopoeiaCustomized] =
    useState(false);
  const [onomatopoeiaText, setOnomatopoeiaText] = useState(() =>
    buildDefaultOnomatopoeiaText({
      themeDescription: DEFAULT_THEME_DESCRIPTION,
      playerImageDescription: DEFAULT_PLAYER_IMAGE_DESCRIPTION,
      opponentImageDescription: DEFAULT_OPPONENT_IMAGE_DESCRIPTION,
    }),
  );
  const [difficultyPreset, setDifficultyPreset] = useState<BarkBattleDifficultyPreset>('normal');
  const [localError, setLocalError] = useState<string | null>(null);

  useEffect(() => {
    if (isOnomatopoeiaCustomized) {
      return;
    }
    setOnomatopoeiaText(
      buildDefaultOnomatopoeiaText({
        themeDescription,
        playerImageDescription,
        opponentImageDescription,
      }),
    );
  }, [
    isOnomatopoeiaCustomized,
    themeDescription,
    playerImageDescription,
    opponentImageDescription,
  ]);

  const onomatopoeia = useMemo(
    () =>
      onomatopoeiaText
        .split(/[\n,，、/|]+/u)
        .map((word) => word.trim())
        .filter(Boolean)
        .slice(0, 24),
    [onomatopoeiaText],
  );

  const payload = useMemo<BarkBattleConfigEditorPayload>(
    () => ({
      title: title.trim(),
      description: description.trim(),
      themeDescription: themeDescription.trim(),
      playerImageDescription: playerImageDescription.trim(),
      opponentImageDescription: opponentImageDescription.trim(),
      onomatopoeia,
      difficultyPreset,
    }),
    [
      title,
      description,
      themeDescription,
      playerImageDescription,
      opponentImageDescription,
      onomatopoeia,
      difficultyPreset,
    ],
  );

  const runValidatedAction = (
    action: (payload: BarkBattleConfigEditorPayload) => void | Promise<void>,
  ) => {
    if (!payload.title) {
      setLocalError('请先填写作品标题');
      return;
    }
    if (!payload.themeDescription) {
      setLocalError('请先填写主题/场景描述');
      return;
    }
    if (!payload.playerImageDescription || !payload.opponentImageDescription) {
      setLocalError('请先填写双方形象描述');
      return;
    }
    setLocalError(null);
    void action(payload);
  };
  const visibleError = localError ?? externalError;

  return (
    <section
      className="platform-remap-surface mx-auto flex min-h-full w-full max-w-5xl flex-col overflow-visible lg:min-h-0 lg:flex-1 lg:overflow-y-auto lg:overscroll-y-contain lg:pr-0.5"
      aria-label="汪汪声浪轻配置编辑器"
    >
      {showBackButton && onBack ? (
        <div className="mb-3 flex shrink-0 items-center justify-between gap-3 sm:mb-4">
          <button
            type="button"
            onClick={onBack}
            disabled={isBusy}
            className={`platform-button platform-button--ghost min-h-0 self-start px-3 py-1.5 text-[11px] ${isBusy ? 'opacity-45' : ''}`}
          >
            <span className="inline-flex items-center gap-1.5">
              <ArrowLeft className="h-3.5 w-3.5" />
              返回
            </span>
          </button>
        </div>
      ) : null}

      <div className="flex min-h-0 flex-col lg:flex-1">
        {headingTitle ? (
          <div className="mb-3 shrink-0 sm:mb-5">
            <div className="flex flex-wrap items-center gap-2">
              <h1 className="m-0 text-3xl font-black leading-none tracking-normal text-[var(--platform-text-strong)] sm:text-7xl">
                {headingTitle}
              </h1>
              <span className="rounded-full border border-emerald-200 bg-emerald-50 px-3 py-1 text-[11px] font-black text-emerald-700">
                轻配置
              </span>
            </div>
          </div>
        ) : null}

        <div
          className={`grid gap-3 lg:flex-1 lg:grid-cols-[minmax(0,1.12fr)_minmax(17rem,0.88fr)] ${isBusy ? 'opacity-55' : ''}`}
        >
          <div className="flex flex-col gap-3 pr-0 lg:pr-1">
            <label className="block shrink-0">
              <span className={FIELD_LABEL_CLASS}>作品标题</span>
              <input
                value={title}
                disabled={isBusy}
                onChange={(event) => setTitle(event.target.value)}
                className="h-11 w-full rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 text-base font-semibold text-[var(--platform-text-strong)] outline-none transition focus:border-[var(--platform-surface-hover-border)] focus:bg-white focus:ring-2 focus:ring-[var(--platform-warm-border)]"
                maxLength={40}
                aria-label="作品标题"
              />
            </label>

            <label className="block shrink-0">
              <span className={FIELD_LABEL_CLASS}>简介</span>
              <textarea
                value={description}
                disabled={isBusy}
                onChange={(event) => setDescription(event.target.value)}
                className="h-[5.5rem] min-h-[5.5rem] w-full resize-none rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 py-3 text-base leading-6 text-[var(--platform-text-strong)] outline-none transition focus:border-[var(--platform-surface-hover-border)] focus:bg-white focus:ring-2 focus:ring-[var(--platform-warm-border)]"
                maxLength={160}
                placeholder=""
                aria-label="简介"
              />
            </label>

            <div className="grid shrink-0 gap-2.5 sm:grid-cols-2">
              <label className="block">
                <span className={FIELD_LABEL_CLASS}>难度预设</span>
                <select
                  value={difficultyPreset}
                  disabled={isBusy}
                  onChange={(event) =>
                    setDifficultyPreset(
                      event.target.value as BarkBattleDifficultyPreset,
                    )
                  }
                  className="h-11 w-full rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 text-sm font-black text-[var(--platform-text-strong)] outline-none transition focus:border-[var(--platform-surface-hover-border)] focus:bg-white focus:ring-2 focus:ring-[var(--platform-warm-border)]"
                  aria-label="难度预设"
                >
                  {DIFFICULTY_OPTIONS.map((option) => (
                    <option key={option.value} value={option.value}>
                      {option.label}
                    </option>
                  ))}
                </select>
              </label>
            </div>

            <label className="block shrink-0">
              <span className={ACCENT_FIELD_LABEL_CLASS}>
                主题/场景描述
              </span>
              <textarea
                value={themeDescription}
                disabled={isBusy}
                onChange={(event) => setThemeDescription(event.target.value)}
                className="h-[5.5rem] min-h-[5.5rem] w-full resize-none rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 py-3 text-base leading-6 text-[var(--platform-text-strong)] outline-none transition focus:border-rose-200 focus:bg-white focus:ring-2 focus:ring-rose-100"
                maxLength={240}
                placeholder=""
                aria-label="主题/场景描述"
              />
            </label>

            <div className="grid shrink-0 gap-2.5 sm:grid-cols-2">
              <label className="block">
                <span className={FIELD_LABEL_CLASS}>玩家形象描述</span>
                <textarea
                  value={playerImageDescription}
                  disabled={isBusy}
                  onChange={(event) => setPlayerImageDescription(event.target.value)}
                  className="h-[5rem] min-h-[5rem] w-full resize-none rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 py-3 text-sm font-semibold leading-6 text-[var(--platform-text-strong)] outline-none transition focus:border-rose-200 focus:bg-white focus:ring-2 focus:ring-rose-100"
                  maxLength={220}
                  aria-label="玩家形象描述"
                />
              </label>

              <label className="block">
                <span className={FIELD_LABEL_CLASS}>对手形象描述</span>
                <textarea
                  value={opponentImageDescription}
                  disabled={isBusy}
                  onChange={(event) => setOpponentImageDescription(event.target.value)}
                  className="h-[5rem] min-h-[5rem] w-full resize-none rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 py-3 text-sm font-semibold leading-6 text-[var(--platform-text-strong)] outline-none transition focus:border-rose-200 focus:bg-white focus:ring-2 focus:ring-rose-100"
                  maxLength={220}
                  aria-label="对手形象描述"
                />
              </label>
            </div>

            <label className="block shrink-0">
              <span className={ACCENT_FIELD_LABEL_CLASS}>拟声词</span>
              <textarea
                value={onomatopoeiaText}
                disabled={isBusy}
                onChange={(event) => {
                  setIsOnomatopoeiaCustomized(true);
                  setOnomatopoeiaText(event.target.value);
                }}
                className="h-[6.5rem] min-h-[6.5rem] w-full resize-none rounded-[1.05rem] border border-[var(--platform-subpanel-border)] bg-white/90 px-4 py-3 text-sm font-black leading-6 text-[var(--platform-text-strong)] outline-none transition focus:border-rose-200 focus:bg-white focus:ring-2 focus:ring-rose-100"
                maxLength={260}
                aria-label="拟声词"
              />
            </label>

            {visibleError ? (
              <div className="platform-banner platform-banner--danger shrink-0 rounded-2xl text-sm leading-6">
                {visibleError}
              </div>
            ) : null}
          </div>

          <BarkBattlePreviewCard config={payload} />
        </div>
      </div>

      <div className="mt-4 flex shrink-0 flex-wrap justify-center gap-2 pb-[calc(env(safe-area-inset-bottom,0px)+0.75rem)] sm:mt-4 lg:pb-[max(0.25rem,env(safe-area-inset-bottom))]">
        <button
          type="button"
          disabled={isBusy}
          onClick={() => runValidatedAction(onPreview)}
          className={`platform-button platform-button--primary min-h-10 px-4 py-2 text-sm sm:min-h-11 sm:px-5 ${isBusy ? 'cursor-not-allowed opacity-55' : ''}`}
        >
          <span className="inline-flex flex-wrap items-center justify-center gap-1.5 sm:gap-2">
            {isBusy ? (
              <Loader2 className="h-4 w-4 animate-spin" />
            ) : (
              <Play className="h-4 w-4" />
            )}
            <span>{isBusy ? '处理中' : '生成草稿'}</span>
          </span>
        </button>
      </div>
    </section>
  );
}
