import React, { useEffect, useMemo, useState } from 'react';
import { createPortal } from 'react-dom';

import type { AppPlayer, AppPlayerTeam, PlayerId, PlayerTeamId } from '../../shared/types';
import { resolveLaunchPlayerIds } from '../../shared/players/resolveLaunchPlayerIds';
import { useAppPlayers } from '../shared/playerToken/useAppPlayers';
import { Button } from '../shared/ui/controls';

import styles from './EditorApp.module.css';
import { useEditorI18n } from './i18n/EditorI18nContext';
import launchStyles from './LaunchPlayersModal.module.css';

export { resolveLaunchPlayerIds } from '../../shared/players/resolveLaunchPlayerIds';

export function LaunchPlayersModal({
  open,
  onClose,
  onConfirm,
}: {
  open: boolean;
  onClose: () => void;
  onConfirm: (playerIds: string[]) => void;
}) {
  const { t } = useEditorI18n();
  const { players, teams } = useAppPlayers();
  const [selectedPlayers, setSelectedPlayers] = useState<Set<string>>(() => new Set());
  const [selectedTeams, setSelectedTeams] = useState<Set<string>>(() => new Set());

  useEffect(() => {
    if (!open) return;
    setSelectedPlayers(new Set());
    setSelectedTeams(new Set());
  }, [open]);

  const resolvedIds = useMemo(
    () => resolveLaunchPlayerIds(players, selectedPlayers, selectedTeams),
    [players, selectedPlayers, selectedTeams],
  );

  const standalonePlayers = useMemo(
    () =>
      players.filter((p) => !(p.teamId && selectedTeams.has(String(p.teamId)))),
    [players, selectedTeams],
  );

  if (!open) return null;

  const togglePlayer = (id: PlayerId) => {
    setSelectedPlayers((prev) => {
      const next = new Set(prev);
      const key = String(id);
      if (next.has(key)) next.delete(key);
      else next.add(key);
      return next;
    });
  };

  const toggleTeam = (id: PlayerTeamId) => {
    const key = String(id);
    setSelectedTeams((prev) => {
      const next = new Set(prev);
      if (next.has(key)) next.delete(key);
      else next.add(key);
      return next;
    });
    // Участники выбранной команды не показываются в «Игроки» — снимаем их индивидуальный выбор.
    setSelectedPlayers((prev) => {
      if (prev.size === 0) return prev;
      const next = new Set(prev);
      let changed = false;
      for (const p of players) {
        if (String(p.teamId) !== key) continue;
        if (next.delete(String(p.id))) changed = true;
      }
      return changed ? next : prev;
    });
  };

  return createPortal(
    <>
      <div className={styles.modalBackdrop} aria-hidden onClick={onClose} />
      <div
        className={[styles.modalDialog, launchStyles.dialog].join(' ')}
        role="dialog"
        aria-modal="true"
        data-testid="launch-players-modal"
      >
        <div className={styles.modalHeader}>
          <div className={styles.modalTitle}>{t('top.runWithPlayersTitle')}</div>
          <button
            type="button"
            aria-label={t('common.close')}
            onClick={onClose}
            className={styles.modalClose}
          >
            ×
          </button>
        </div>
        <div>
          <p className={launchStyles.hint}>{t('top.runWithPlayersHint')}</p>
          {teams.length > 0 ? (
            <section className={launchStyles.section}>
              <div className={launchStyles.sectionTitle}>{t('top.runWithPlayersTeams')}</div>
              <div className={launchStyles.list}>
                {teams.map((team: AppPlayerTeam) => {
                  const count = players.filter((p) => p.teamId === team.id).length;
                  return (
                    <label key={team.id} className={launchStyles.row}>
                      <input
                        type="checkbox"
                        checked={selectedTeams.has(String(team.id))}
                        onChange={() => toggleTeam(team.id)}
                        data-testid={`launch-team-${team.id}`}
                      />
                      <span className={launchStyles.teamDot} style={{ background: team.color }} />
                      <span>
                        {team.name} ({count})
                      </span>
                    </label>
                  );
                })}
              </div>
            </section>
          ) : null}
          {standalonePlayers.length > 0 ? (
            <section className={launchStyles.section}>
              <div className={launchStyles.sectionTitle}>{t('top.runWithPlayersPlayers')}</div>
              <div className={launchStyles.list}>
                {standalonePlayers.map((player: AppPlayer) => (
                  <label key={player.id} className={launchStyles.row}>
                    <input
                      type="checkbox"
                      checked={selectedPlayers.has(String(player.id))}
                      onChange={() => togglePlayer(player.id)}
                      data-testid={`launch-player-${player.id}`}
                    />
                    <span>{player.name}</span>
                  </label>
                ))}
              </div>
            </section>
          ) : players.length === 0 ? (
            <section className={launchStyles.section}>
              <div className={launchStyles.empty}>{t('top.runWithPlayersEmpty')}</div>
            </section>
          ) : null}
        </div>
        <div className={styles.modalFooter}>
          <Button variant="ghost" onClick={onClose}>
            {t('common.cancel')}
          </Button>
          <Button
            variant="primary"
            disabled={resolvedIds.length === 0}
            data-testid="launch-players-confirm"
            onClick={() => onConfirm(resolvedIds)}
          >
            {t('top.runWithPlayersConfirm')}
          </Button>
        </div>
      </div>
    </>,
    document.body,
  );
}
