import Alpine from 'alpinejs';
import { createGameRequest, fetchModes, requireAuth } from './game';

Alpine.data('playersHandler', ({ redirectBasePath = '/games', selectedModeKey = '' } = {}) => ({
    storageKey: 'dart-board-player-names',
    redirectBasePath,
    selectedModeKey,
    isSubmitting: false,
    loading: true,
    errorMessage: '',
    modes: [],
    throwRules: [],
    selectedMode: null,
    inRule: 'ANY',
    outRule: 'ANY',
    players: [
        { name: '', position: 0 },
        { name: '', position: 1 }
    ],

    async init() {
        if (!await requireAuth()) return;

        this.restorePlayerNames();

        try {
            const data = await fetchModes();
            this.modes = data.modes || [];
            this.throwRules = data.throwRules || [];

            if (this.selectedModeKey !== '') {
                this.selectedMode = this.modes.find((m) => m.key === this.selectedModeKey) || null;
            }

            if (!this.modeUsesThrowRules()) {
                this.inRule = 'ANY';
                this.outRule = 'ANY';
            }
        } catch (error) {
            this.errorMessage = error instanceof Error ? error.message : 'Daten konnten nicht geladen werden.';
        } finally {
            this.loading = false;
        }
    },

    selectMode(mode) {
        this.selectedMode = mode;
        this.selectedModeKey = mode.key;
        if (!this.modeUsesThrowRules()) {
            this.inRule = 'ANY';
            this.outRule = 'ANY';
        }
    },

    modeUsesThrowRules() {
        return String(this.selectedMode?.type || 'X01') === 'X01';
    },

    restorePlayerNames() {
        const raw = window.localStorage.getItem(this.storageKey);
        if (!raw) return;

        try {
            const names = JSON.parse(raw);
            if (!Array.isArray(names)) return;

            const normalized = names
                .map((name) => String(name ?? '').trim())
                .filter((name) => name !== '');

            if (normalized.length === 0) return;

            this.players = normalized.map((name, index) => ({
                name,
                position: index
            }));
        } catch (error) {
            window.localStorage.removeItem(this.storageKey);
        }
    },

    persistPlayerNames() {
        const names = this.players
            .map((player) => String(player.name ?? '').trim())
            .filter((name) => name !== '');

        if (names.length === 0) {
            window.localStorage.removeItem(this.storageKey);
            return;
        }

        window.localStorage.setItem(this.storageKey, JSON.stringify(names));
    },

    async createGame() {
        if (this.isSubmitting) return;

        this.errorMessage = '';

        const modeKey = this.selectedMode?.key || '';
        if (modeKey === '') {
            this.errorMessage = 'Bitte zuerst einen Modus auswählen.';
            return;
        }

        if (!this.modeUsesThrowRules()) {
            this.inRule = 'ANY';
            this.outRule = 'ANY';
        }

        const preparedPlayers = this.players
            .map((player, index) => ({
                name: String(player.name || '').trim(),
                position: Number.isInteger(player.position) ? player.position : Number(player.position) || index
            }))
            .filter((player) => player.name !== '')
            .sort((a, b) => a.position - b.position);

        if (preparedPlayers.length === 0) {
            this.errorMessage = 'Bitte mindestens einen Spielernamen eingeben.';
            return;
        }

        this.persistPlayerNames();
        this.isSubmitting = true;

        try {
            const payload = await createGameRequest({
                modeKey,
                inRule: this.modeUsesThrowRules() ? this.inRule : 'ANY',
                outRule: this.modeUsesThrowRules() ? this.outRule : 'ANY',
                players: preparedPlayers
            });

            const gameId = String(payload?.game?.id || '').trim();
            if (gameId === '') {
                throw new Error('Serverantwort enthält keine Spiel-ID.');
            }

            window.location.href = `${this.redirectBasePath}/${gameId}`;
        } catch (error) {
            this.errorMessage = error instanceof Error ? error.message : 'Spiel konnte nicht erstellt werden.';
        } finally {
            this.isSubmitting = false;
        }
    },

    addRow() {
        this.players.push({ name: '', position: this.players.length });
        this.persistPlayerNames();
    },

    removeRow(index) {
        if (this.players.length <= 1) return;
        this.players.splice(index, 1);
        this.players = this.players.map((player, i) => ({ ...player, position: i }));
        this.persistPlayerNames();
    }
}));
