import { Modal } from '../Modal';
import { Icon } from '../Icon';
import { GameCover } from '../grid/GameCover';
import { StateChip } from '../StateChip';
import { ActionButton } from '../ActionButton';

import { Game, InstallStatus } from '../../lib/types';
import { deriveState, hasNewerLocalVersion, isInProgress } from '../../lib/gameState';
import { formatBytes, formatEtiVersion, formatPlayers } from '../../lib/format';

interface Props {
    game: Game;
    thumbnailUrl: string | null;
    onClose: () => void;
    onPrimary: (game: Game) => void;
    onUninstall: (game: Game) => void;
    onRemoveDownload: (game: Game) => void;
    onCancelDownload: (game: Game) => void;
    onStartServer: (game: Game) => void;
    onViewFiles: (game: Game) => void;
}

const tagsFromGame = (game: Game): string[] => {
    const tags: string[] = [];
    if (game.genre) tags.push(game.genre);
    if (game.publisher) tags.push(game.publisher);
    if (game.release_year) tags.push(game.release_year);
    return tags;
};

const statusLabelFor = (game: Game): string => {
    switch (deriveState(game)) {
        case 'installed': return 'Installed';
        case 'local': return 'Downloaded';
        case 'downloading': return 'Downloading';
        case 'busy': return 'Working…';
        case 'none': return 'Not downloaded';
    }
};

export const GameDetailModal = ({
    game,
    thumbnailUrl,
    onClose,
    onPrimary,
    onUninstall,
    onRemoveDownload,
    onCancelDownload,
    onStartServer,
    onViewFiles,
}: Props) => {
    const tags = tagsFromGame(game);
    // Some game metadata contains a literal <br>; keep sanitization exact.
    const description = game.description.split('<br>').join('');
    const canRemoveDownload = game.downloaded
        && !game.installed
        && !isInProgress(game.install_status);
    const canViewFiles = game.downloaded
        || game.installed
        || game.install_status === InstallStatus.Downloading
        || game.install_status === InstallStatus.Installing;
    const newerThanExpected = hasNewerLocalVersion(game);
    const newerStatus = newerThanExpected
        ? `Local version ${formatEtiVersion(game.local_version)} is newer than expected ${formatEtiVersion(game.eti_game_version)}.`
        : undefined;
    const hasOutbound = game.active_outbound_transfers !== undefined && game.active_outbound_transfers > 0;
    const outboundStatus = hasOutbound
        ? `Sharing to ${game.active_outbound_transfers} peer${game.active_outbound_transfers === 1 ? '' : 's'}.`
        : undefined;
    const statusMessage = outboundStatus ?? game.status_message ?? newerStatus;
    const statusLevel = hasOutbound
        ? 'info'
        : (game.status_level ?? (newerStatus ? 'warning' : undefined));
    return (
        <Modal onClose={onClose}>
            <button className="modal-close" type="button" onClick={onClose} aria-label="Close">
                <Icon.close />
            </button>
            <div className="modal-hero">
                <GameCover game={game} aspect="banner" thumbnailUrl={thumbnailUrl} hideTitle />
                <div className="modal-hero-fade" />
                <div className="modal-hero-text">
                    {tags.length > 0 && (
                        <div className="modal-tags">
                            {tags.map(t => <span key={t} className="modal-tag">{t}</span>)}
                        </div>
                    )}
                    <h2 className="modal-title">{game.name}</h2>
                </div>
                <div className="modal-state">
                    <StateChip game={game} showNone />
                </div>
            </div>

            <div className="modal-body">
                <div className="modal-meta">
                    <div className="meta-cell">
                        <div className="meta-label">Size</div>
                        <div className="meta-value">{formatBytes(game.size)}</div>
                    </div>
                    <div className="meta-cell">
                        <div className="meta-label">Players</div>
                        <div className="meta-value">
                            <Icon.users /> {formatPlayers(game.max_players)}
                        </div>
                    </div>
                    <div className="meta-cell">
                        <div className="meta-label">Version</div>
                        <div className="meta-value meta-mono">
                            {formatEtiVersion(game.eti_game_version ?? game.local_version)}
                        </div>
                    </div>
                    <div className="meta-cell">
                        <div className="meta-label">Status</div>
                        <div className="meta-value">{statusLabelFor(game)}</div>
                    </div>
                </div>

                {description && (
                    <p className="modal-desc">{description}</p>
                )}

                {statusMessage && (
                    <p className={`modal-status${statusLevel ? ` is-${statusLevel}` : ''}`}>
                        {statusMessage}
                    </p>
                )}

                <div className="modal-actions">
                    <ActionButton
                        game={game}
                        size="lg"
                        onClick={() => onPrimary(game)}
                        onCancelDownload={onCancelDownload}
                    />
                    {game.installed && game.can_host_server === true && (
                        <button
                            type="button"
                            className="act-btn act-lg act-server"
                            onClick={() => onStartServer(game)}
                        >
                            <Icon.server />
                            <span className="act-label">Start Server</span>
                        </button>
                    )}
                    {game.installed && (
                        <button
                            type="button"
                            className="ghost-btn ghost-danger"
                            onClick={() => onUninstall(game)}
                        >
                            <Icon.trash />
                            <span>Uninstall</span>
                        </button>
                    )}
                    {canRemoveDownload && (
                        <button
                            type="button"
                            className="ghost-btn ghost-danger"
                            onClick={() => onRemoveDownload(game)}
                        >
                            <Icon.trash />
                            <span>Remove files</span>
                        </button>
                    )}
                    {canViewFiles && (
                        <>
                            <div className="modal-actions-spacer" />
                            <button
                                type="button"
                                className="ghost-btn"
                                onClick={() => onViewFiles(game)}
                            >
                                <Icon.folder />
                                <span>View Files</span>
                            </button>
                        </>
                    )}
                </div>
            </div>
        </Modal>
    );
};
