import type { ComponentType, CSSProperties, ReactNode } from 'react';
import { RefreshCcw } from 'lucide-react';

import {
  type AnimationState,
  type Character,
} from '../../types';
import { CORE_ACTIONS } from './roleAssetStudioModel';

type ActionButtonProps = {
  icon?: ReactNode;
  label: string;
  subLabel?: string;
  onClick: () => void;
  disabled?: boolean;
  tone?: 'default' | 'sky' | 'green';
};

type FieldProps = {
  label: string;
  children: ReactNode;
};

type SectionProps = {
  title: string;
  children: ReactNode;
};

type StatusBadgeProps = {
  tone: 'green' | 'amber' | 'zinc';
  children: ReactNode;
};

type TextAreaProps = {
  value: string;
  onChange: (value: string) => void;
  rows?: number;
  placeholder?: string;
  readOnly?: boolean;
};

type CharacterAnimatorProps = {
  state: AnimationState;
  character: Character;
  className?: string;
  style?: CSSProperties;
  imageClassName?: string;
  playbackRate?: number;
};

export function RpgCreationRoleAnimationSection(props: {
  ActionButton: (props: ActionButtonProps) => ReactNode;
  CharacterAnimator: ComponentType<CharacterAnimatorProps>;
  Field: (props: FieldProps) => ReactNode;
  Section: (props: SectionProps) => ReactNode;
  StatusBadge: (props: StatusBadgeProps) => ReactNode;
  TextArea: (props: TextAreaProps) => ReactNode;
  animationPreviewFrameStyle: CSSProperties;
  animationPreviewPlaybackRate: number;
  animationPreviewViewportStyle: CSSProperties;
  animationPromptText: string;
  generatingAnimationMap: Partial<Record<AnimationState, boolean>>;
  hasGeneratedAnimation: (animation: AnimationState) => boolean;
  isSelectedAnimationGenerating: boolean;
  previewCharacter: Character | null;
  previewImageSrc: string;
  selectedAnimation: AnimationState;
  selectedAnimationStatus: string | null;
  shouldUseSelectedAnimationPreview: boolean;
  syncBusy: boolean;
  animationPointCost: number;
  workingRoleImageSrc?: string;
  workingRoleGeneratedVisualAssetId?: string;
  workingRoleName: string;
  onAnimationPromptChange: (value: string) => void;
  onGenerateAnimation: () => void;
  onPlaybackRateChange: (value: number) => void;
  onSelectAnimation: (animation: AnimationState) => void;
}) {
  const {
    ActionButton,
    CharacterAnimator,
    Field,
    Section,
    StatusBadge,
    TextArea,
    animationPreviewFrameStyle,
    animationPreviewPlaybackRate,
    animationPreviewViewportStyle,
    animationPromptText,
    generatingAnimationMap,
    hasGeneratedAnimation,
    isSelectedAnimationGenerating,
    previewCharacter,
    previewImageSrc,
    selectedAnimation,
    selectedAnimationStatus,
    shouldUseSelectedAnimationPreview,
    syncBusy,
    animationPointCost,
    workingRoleGeneratedVisualAssetId,
    workingRoleImageSrc,
    workingRoleName,
    onAnimationPromptChange,
    onGenerateAnimation,
    onPlaybackRateChange,
    onSelectAnimation,
  } = props;

  return (
    <Section title="动作">
      <div className="space-y-4">
        <div className="platform-role-studio__preview rounded-3xl p-4">
          <div className="platform-role-studio__stage flex min-h-[28rem] items-center justify-center rounded-2xl p-4">
            {shouldUseSelectedAnimationPreview && previewCharacter ? (
              <div
                className="flex items-center justify-center"
                style={animationPreviewViewportStyle}
              >
                <div style={animationPreviewFrameStyle}>
                  <CharacterAnimator
                    state={selectedAnimation}
                    character={previewCharacter}
                    className="h-full w-full"
                  />
                </div>
              </div>
            ) : previewImageSrc ? (
              <img
                src={previewImageSrc}
                alt={workingRoleName}
                className="max-h-[28rem] w-full object-contain pixelated"
              />
            ) : (
              <div className="px-4 text-sm text-zinc-500">暂无动作预览</div>
            )}
          </div>
        </div>

        <Field label="预览速度">
          <div className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3">
            <input
              type="range"
              min="0.25"
              max="1.5"
              step="0.05"
              value={animationPreviewPlaybackRate}
              onChange={(event) =>
                onPlaybackRateChange(Number.parseFloat(event.target.value) || 0.75)
              }
              className="w-full accent-sky-400"
            />
            <div className="mt-2 flex items-center justify-between text-[11px] text-zinc-400">
              <span>0.25x</span>
              <span>{animationPreviewPlaybackRate.toFixed(2)}x</span>
              <span>1.50x</span>
            </div>
          </div>
        </Field>

        <div className="grid grid-cols-2 gap-2 sm:grid-cols-3 lg:grid-cols-5">
          {CORE_ACTIONS.map((item) => {
            const isSelected = item.animation === selectedAnimation;
            const isReady = hasGeneratedAnimation(item.animation);
            const isGenerating = generatingAnimationMap[item.animation] === true;

            return (
              <button
                key={item.animation}
                type="button"
                onClick={() => onSelectAnimation(item.animation)}
                className={`rounded-2xl border px-3 py-3 text-left transition-colors ${
                  isSelected
                    ? 'border-sky-300/30 bg-sky-500/10'
                    : 'border-white/10 bg-black/20 hover:border-white/20'
                }`}
              >
                <div className="flex items-start justify-between gap-2">
                  <div className="min-w-0">
                    <div className="text-sm font-semibold text-white">
                      {item.label}
                    </div>
                    <div className="mt-1 flex flex-wrap items-center gap-2 text-[11px] text-zinc-400">
                      {isGenerating
                        ? '后台生成中'
                        : isSelected
                          ? '当前预览'
                          : '点击切换'}
                      <span>{item.required ? '必需动作' : '可选动作'}</span>
                    </div>
                  </div>
                  <StatusBadge
                    tone={isGenerating ? 'amber' : isReady ? 'green' : 'zinc'}
                  >
                    {isGenerating
                      ? '生成中'
                      : isReady
                        ? '已生成'
                        : item.required
                          ? '待生成'
                          : (item.fallbackStatusLabel ?? '可选')}
                  </StatusBadge>
                </div>
              </button>
            );
          })}
        </div>

        <Field label="动作描述">
          <TextArea
            value={animationPromptText}
            onChange={onAnimationPromptChange}
            rows={5}
            placeholder="这里默认展示角色动作描述，也可以继续手动细化。"
          />
        </Field>

        <div className="flex flex-wrap gap-3">
          <ActionButton
            icon={<RefreshCcw className="h-4 w-4" />}
            label={isSelectedAnimationGenerating ? '生成中...' : '生成动作'}
            subLabel={`消耗${animationPointCost}叙世币`}
            onClick={onGenerateAnimation}
            disabled={
              isSelectedAnimationGenerating ||
              !workingRoleImageSrc ||
              !workingRoleGeneratedVisualAssetId ||
              syncBusy
            }
            tone="sky"
          />
        </div>

        {selectedAnimationStatus ? (
          <div className="rounded-2xl border border-white/10 bg-black/20 px-4 py-3 text-sm text-zinc-300">
            {selectedAnimationStatus}
          </div>
        ) : null}
      </div>
    </Section>
  );
}

export default RpgCreationRoleAnimationSection;
