import React, { useMemo } from 'react';

import { isNpcBindingNone, listStorylineOptionsForBinding, noneBinding } from '../../shared/npcs/npcBinding';
import type { GraphNodeId, NpcBinding, Project, SceneId } from '../../shared/types';
import editorStyles from '../editor/EditorApp.module.css';
import { useEditorI18n } from '../editor/i18n/EditorI18nContext';
import controlStyles from '../shared/ui/Controls.module.css';

type NpcBindingFieldsProps = {
  project: Project;
  binding: NpcBinding;
  onChange: (binding: NpcBinding) => void;
};

function defaultBinding(project: Project): NpcBinding {
  const opts = listStorylineOptionsForBinding(project);
  if (opts.main) return { kind: 'storyline', storyline: { kind: 'main' } };
  if (opts.sides[0]) {
    return {
      kind: 'storyline',
      storyline: { kind: 'side', startGraphNodeId: opts.sides[0].startGraphNodeId },
    };
  }
  const firstScene = Object.keys(project.scenes)[0] as SceneId | undefined;
  if (firstScene) return { kind: 'scene', sceneId: firstScene };
  return noneBinding();
}

export function NpcBindingFields({ project, binding, onChange }: NpcBindingFieldsProps) {
  const { t } = useEditorI18n();
  const enabled = !isNpcBindingNone(binding);
  const storylineOpts = useMemo(() => listStorylineOptionsForBinding(project), [project]);
  const sceneOptions = useMemo(
    () =>
      Object.entries(project.scenes)
        .map(([id, scene]) => ({ id: id as SceneId, title: scene.title.trim() || id }))
        .sort((a, b) => a.title.localeCompare(b.title, undefined, { sensitivity: 'base' })),
    [project.scenes],
  );

  const kind = binding.kind === 'none' ? 'storyline' : binding.kind;

  const bindingTargetValue = useMemo(() => {
    if (binding.kind === 'scene') return binding.sceneId;
    if (binding.kind === 'storyline') {
      if (binding.storyline.kind === 'main') return 'main';
      return `side:${binding.storyline.startGraphNodeId}`;
    }
    return '';
  }, [binding]);

  return (
    <div className={editorStyles.fieldGrid}>
      <label style={{ display: 'flex', alignItems: 'center', gap: 8, fontSize: 13, cursor: 'pointer' }}>
        <input
          type="checkbox"
          checked={enabled}
          onChange={(e) => {
            onChange(e.target.checked ? defaultBinding(project) : noneBinding());
          }}
        />
        <span>{t('npcs.bindingEnable')}</span>
      </label>

      {enabled ? (
        <>
          <div className={editorStyles.fieldLabel}>{t('npcs.bindingKind')}</div>
          <select
            className={controlStyles.input}
            value={kind}
            onChange={(e) => {
              const nextKind = e.target.value;
              if (nextKind === 'scene') {
                const first = sceneOptions[0];
                onChange(first ? { kind: 'scene', sceneId: first.id } : noneBinding());
                return;
              }
              if (storylineOpts.main) {
                onChange({ kind: 'storyline', storyline: { kind: 'main' } });
              } else if (storylineOpts.sides[0]) {
                onChange({
                  kind: 'storyline',
                  storyline: { kind: 'side', startGraphNodeId: storylineOpts.sides[0].startGraphNodeId },
                });
              } else {
                onChange(noneBinding());
              }
            }}
          >
            <option value="storyline">{t('npcs.bindingStoryline')}</option>
            <option value="scene">{t('npcs.bindingScene')}</option>
          </select>

          <div className={editorStyles.fieldLabel}>{t('npcs.bindingSelect')}</div>
          <select
            className={controlStyles.input}
            value={bindingTargetValue}
            onChange={(e) => {
              const v = e.target.value;
              if (kind === 'scene') {
                onChange({ kind: 'scene', sceneId: v as SceneId });
                return;
              }
              if (v === 'main') {
                onChange({ kind: 'storyline', storyline: { kind: 'main' } });
                return;
              }
              if (v.startsWith('side:')) {
                onChange({
                  kind: 'storyline',
                  storyline: {
                    kind: 'side',
                    startGraphNodeId: v.slice(5) as GraphNodeId,
                  },
                });
              }
            }}
          >
            {kind === 'storyline' ? (
              <>
                {storylineOpts.main ? <option value="main">{t('npcs.bindingMain')}</option> : null}
                {storylineOpts.sides.map((s) => (
                  <option key={s.startGraphNodeId} value={`side:${s.startGraphNodeId}`}>
                    {s.label}
                  </option>
                ))}
              </>
            ) : (
              sceneOptions.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.title}
                </option>
              ))
            )}
          </select>
        </>
      ) : null}
    </div>
  );
}
