import {Class, MedigunType, PlayerState, SpyState} from "../Data/Parser";

export interface PlayerSpecProps {
    player: PlayerState;
    onHover: (userId: number) => void;
    highlighted: boolean;
}

const healthMap = {
    0: 100, //fallback
    1: 125, //scout
    2: 150, //sniper
    3: 200, //soldier,
    4: 175, //demoman,
    5: 150, //medic,
    6: 300, //heavy,
    7: 175, //pyro
    8: 125, //spy
    9: 125, //engineer
};

const classMap = {
    1: "scout",
    2: "sniper",
    3: "soldier",
    4: "demoman",
    5: "medic",
    6: "heavy",
    7: "pyro",
    8: "spy",
    9: "engineer"
};

const classSort = {
    1: 1, //scout
    3: 2, //soldier
    7: 3, //pyro
    4: 4, //demoman
    6: 5, //heavy
    9: 6, //engineer
    5: 7, //medic
    2: 8, //sniper
    8: 9, //spy
};

const teamMap = {
    0: "other",
    1: "spectator",
    2: "red",
    3: "blue",
}

export interface PlayersSpecProps {
    players: PlayerState[];
    onHover: (userId: number) => void;
    highlighted: number;
}

function sortPlayer(a, b) {
    return classSort[a.playerClass] - classSort[b.playerClass];
}

function filterPlayers(players: PlayerState[], team: number): PlayerState[] {
    const filtered = players.filter((player) => player.team === team);
    filtered.sort(sortPlayer);
    return filtered;
}

export function medics(players: PlayerState[]): PlayerState[] {
    return players.filter(player => player.playerClass === Class.Medic);
}

export function PlayersSpec(props: PlayersSpecProps) {
    const redPlayers = () => filterPlayers(props.players, 2);
    const bluePlayers = () => filterPlayers(props.players, 3);
    const redMedics = () => medics(redPlayers());
    const blueMedics = () => medics(bluePlayers());

    return (<div>
        <div class="redSpecHolder">
            <For each={redPlayers()}>{(player: PlayerState) =>
                <PlayerSpec player={player} highlighted={player.info.userId == props.highlighted}
                            onHover={props.onHover}/>
            }</For>
            <For each={redMedics()}>{(player) =>
                <UberSpec
                    team={teamMap[player.team]}
                    chargeLevel={player.class_data.charge}
                    medigun={player.class_data.medigun}
                    isDeath={player.health < 1}
                />
            }</For>
        </div>
        <div class="blueSpecHolder">
            <For each={bluePlayers()}>{(player) =>
                <PlayerSpec player={player} highlighted={player.info.userId == props.highlighted}
                            onHover={props.onHover}/>
            }</For>
            <For each={blueMedics()}>{(player) =>
                <UberSpec
                    team={teamMap[player.team]}
                    chargeLevel={player.class_data.charge}
                    medigun={player.class_data.medigun}
                    isDeath={player.health < 1}
                />
            }</For>
        </div>
    </div>);
}

export function PlayerSpec(props: PlayerSpecProps) {
    const healthPercent = () => Math.min(100, props.player.health / healthMap[props.player.playerClass] * 100);
    const healthStatusClass = () => (props.player.health > healthMap[props.player.playerClass]) ? 'overhealed' : (props.player.health <= 0 ? 'dead' : '');

    return (
        <div
            onmouseover={() => props.onHover(props.player.info.userId)}
            onmouseout={() => props.onHover(0)}
            classList={{
                "playerspec": true,
                [teamMap[props.player.team]]: true,
                "webp": true,
                [healthStatusClass()]: true,
                highlighted: props.highlighted,
            }}>
            {getPlayerIcon(props.player)}
            <div class="health-container">
                <div class="healthbar"
                     style={{width: healthPercent() + '%'}}/>
                <span class="player-name">{props.player.info.name}</span>
                <span class="health">{props.player.health}</span>
            </div>
        </div>
    );
}

function getPlayerIcon(player: PlayerState) {
    if (classMap[player.playerClass]) {
        const className = classMap[player.playerClass];
        if (player.playerClass === Class.Spy && classMap[(player.class_data as SpyState).disguise_class]) {
            const disguiseClassName = classMap[(player.class_data as SpyState).disguise_class];
            return (<div class={className + " class-icon"}>
                <div class={disguiseClassName + " disguise"}/>
            </div>)
        } else {
            return <div class={className + " class-icon"}/>
        }
    } else {
        return <div class={"class-icon"}/>
    }
}

export interface UberSpecProps {
    chargeLevel: number;
    medigun: MedigunType;
    team: string;
    isDeath: boolean;
}

export function UberSpec(props: UberSpecProps) {
    const healthStatusClass = (props.isDeath) ? 'dead' : '';
    const medigunName = () => {
        switch (props.medigun) {
            case MedigunType.Kritzkrieg:
                return "Kritzkrieg";
            case MedigunType.Quickfix:
                return "Quickfix";
            case MedigunType.Vaccinator:
                return "Vaccinator";
            default:
                return "Ubercharge";
        }
    }
    return (
        <div class={`playerspec uber ${props.team} ${healthStatusClass}`}>
            <div class={"uber class-icon"}/>
            <div class="health-container">
                <div class="healthbar"
                     style={{width: props.chargeLevel + '%'}}/>
                <span class="player-name">{medigunName()}</span>
                <span class="health">{Math.round(props.chargeLevel)}</span>
            </div>
        </div>
    );
}
