import { Component, Input, OnInit, inject } from '@angular/core';
import { DatePipe, DecimalPipe } from '@angular/common';
import { MatCardModule } from '@angular/material/card';
import { MatDividerModule } from '@angular/material/divider';
import { MatIconModule } from '@angular/material/icon';

import { FortificationCardContentComponent } from '../fortification-card-content/fortification-card-content.component';
import {
    HWGuildWarEnemySlot,
    HWGuildWarEnemyTeam,
    HWGuildWarFortification,
    HWGuildWarHeroTeam,
    HWGuildWarTitanTeam,
    HWGuildWarSlots,
    HWMember,
} from '@models';
import { HWDataService } from '@services';
import { combineLatest } from 'rxjs';

@Component({
    selector: 'app-guildwar-attack',
    imports: [DatePipe, DecimalPipe, MatCardModule, MatDividerModule, MatIconModule, FortificationCardContentComponent],
    templateUrl: './guildwar-attack.component.html',
    styleUrl: './guildwar-attack.component.scss',
})
export class GuildwarAttackComponent implements OnInit {
    private _dataService = inject(HWDataService);
    private _championsByPower: HWMember[] = [];
    private _enemySlots: number[] = [];
    private _slots: HWGuildWarSlots = {};
    public guildEnemies: HWMember[] = [];
    public guildMembers: HWMember[] = [];
    public title = 'Fortifications';
    public subtitle = 'Guild War Attack';
    public now = new Date();
    public warInfo: { day: number; clanEnemyName: string; endTime: number; nextWarTime: number; nextLockTime: number } =
        {
            day: 0,
            clanEnemyName: '',
            endTime: 0,
            nextWarTime: 0,
            nextLockTime: 0,
        };

    @Input() set members(value: HWMember[]) {
        this.guildMembers = value;
    }

    ngOnInit() {
        combineLatest([
            this._dataService.guildWarData$,
            this._dataService.guildWarInfo$,
            this._dataService.guildWarSlots$,
        ]).subscribe({
            next: ([guildWarData, guildWarInfo, guildWarSlotsData]) => {
                this._slots = guildWarSlotsData.slots;
                this.warInfo.day = parseInt(guildWarInfo.day);
                this.warInfo.clanEnemyName = guildWarInfo.enemyClan.title;
                this.warInfo.endTime = guildWarInfo.endTime * 1000;
                this.warInfo.nextWarTime = guildWarInfo.nextWarTime * 1000;
                this.warInfo.nextLockTime = guildWarInfo.nextLockTime * 1000;
                this._setChampionsByPower(guildWarData);
                this._setEnemies(guildWarInfo);
            },
            error: (err) => console.error(err),
        });
    }

    private _getFortification(indexes: number[], type: string, name: string): HWGuildWarFortification {
        const teams: HWMember[] = [];
        const slots: HWGuildWarSlots = this._slots;
        if (!slots[name]) return { name, type, count: 0, teams: [], positions: this._enemySlots, slots: [] };
        let count = 0;
        indexes.forEach((data) => {
            switch (type) {
                case 'heroes':
                    teams.push(this.guildEnemies[data]);
                    count += this.guildEnemies[data].heroes.power;
                    break;
                case 'titans':
                    teams.push(this.guildEnemies[data]);
                    count += this.guildEnemies[data].titans.power;
                    break;
                default:
                    break;
            }
        });
        return {
            name: name,
            type: type,
            count: count,
            teams: teams,
            positions: this._enemySlots,
            slots: slots[name],
        };
    }

    private _getDefense(type: string, name: string): HWGuildWarFortification {
        const teams: HWMember[] = [];
        const slots: HWGuildWarSlots = this._slots;
        if (!slots[name]) return { name, type, count: 0, teams: [], positions: this._enemySlots, slots: [] };
        let count = 0;
        slots[name].forEach((slot) => {
            let enemies: HWMember[] = [];
            let team: HWMember = {} as HWMember;
            enemies = this.guildEnemies.filter((enemy) => parseInt(enemy.id) === this._enemySlots[slot]);
            if (enemies.length) {
                team = enemies[0];
                teams.push(team);
                switch (type) {
                    case 'heroes':
                        count += team.heroes.power;
                        break;
                    case 'titans':
                        count += team.titans.power;
                        break;
                    default:
                        break;
                }
            }
        });

        return {
            name: name,
            type: type,
            count: count,
            teams: teams,
            positions: this._enemySlots,
            slots: slots[name],
        };
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    private _setEnemies(guildWarInfo: any): void {
        const warriors: number[] = [];
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        for (const data of Object.entries(guildWarInfo.enemyClanTries as Record<string, any>)) {
            warriors.push(parseInt(data[0]));
        }
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        for (const data of Object.entries(guildWarInfo.enemyClanMembers as Record<string, any>)) {
            const enemy: HWMember = {} as HWMember;
            Object.assign(enemy, data[1]);
            if (warriors.indexOf(parseInt(enemy.id)) !== -1) {
                enemy.champion = true;
            } else {
                enemy.champion = false;
            }
            enemy.heroes = { power: 0, teams: [] };
            enemy.titans = { power: 0, teams: [] };

            //console.log(guildWarInfo.enemySlots);

            this.guildEnemies.push(enemy);
        }

        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        for (const data of Object.entries(guildWarInfo.enemySlots as Record<string, any>)) {
            const ennemySlot: HWGuildWarEnemySlot = {} as HWGuildWarEnemySlot;
            Object.assign(ennemySlot, data[1]);
            ennemySlot.teams = [];
            let totalHeroPower = 0;
            let totalTitanPower = 0;
            if (ennemySlot.user !== null) {
                this._enemySlots[ennemySlot.slotId] = parseInt(ennemySlot.user.id);
                // eslint-disable-next-line @typescript-eslint/no-explicit-any
                for (const team of Object.entries(data[1].team[0] as Record<string, any>)) {
                    /*
                    ennemySlot.teams.push(enemyTeam);
                    console.log(enemyTeam);
                    */
                    const enemyTeam: HWGuildWarEnemyTeam = {} as HWGuildWarEnemyTeam;
                    Object.assign(enemyTeam, team[1]);
                    switch (enemyTeam.type) {
                        case 'hero':
                        case 'pet':
                            totalHeroPower += enemyTeam.power;
                            break;
                        case 'titan':
                            totalTitanPower += enemyTeam.power;
                            break;
                        default:
                            break;
                    }
                    ennemySlot.teams.push(team[1]);
                    //console.log(team[1]);
                }
                //console.log(totalHeroPower, totalTitanPower, ennemySlot.teams);

                this.guildEnemies.some((item) => {
                    if (item.id === ennemySlot.user.id) {
                        if (totalHeroPower) {
                            item.heroes.power = totalHeroPower;
                            item.heroes.teams = ennemySlot.teams;
                        }
                        if (totalTitanPower) {
                            item.titans.power = totalTitanPower;
                            item.titans.teams = ennemySlot.teams;
                        }
                        return true;
                    }
                    return false;
                });
            }
            this.guildEnemies.sort((a, b) =>
                a.heroes.power + a.titans.power > b.heroes.power + b.titans.power ? -1 : 1,
            ); // Descending
        }
    }

    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    private _setChampionsByPower(guildWarData: any): void {
        // eslint-disable-next-line @typescript-eslint/no-explicit-any
        for (const [teamId, teamValues] of Object.entries(guildWarData.teams as Record<string, any>)) {
            const index = this.guildMembers.findIndex((member) => member.id === teamId);
            if (index === -1) continue;
            let totalHeroPower = 0;
            let totalTitanPower = 0;
            const heroes: HWGuildWarHeroTeam[] = [];
            const titans: HWGuildWarTitanTeam[] = [];

            for (const unit of Object.entries(
                teamValues.clanDefence_heroes.units as Record<string, HWGuildWarHeroTeam>,
            )) {
                heroes.push(unit[1]);
                totalHeroPower += unit[1].power;
            }
            for (const unit of Object.entries(
                teamValues.clanDefence_titans.units as Record<string, HWGuildWarTitanTeam>,
            )) {
                titans.push(unit[1]);
                totalTitanPower += unit[1].power;
            }
            this.guildMembers[index].heroes = { power: totalHeroPower, teams: heroes };
            this.guildMembers[index].titans = { power: totalTitanPower, teams: titans };
        }
        this.guildMembers.sort((a, b) => (a.heroes.power + a.titans.power > b.heroes.power + b.titans.power ? -1 : 1)); // Descending
        this._championsByPower = this.guildMembers.filter((member) => member.champion === true);
    }

    getEnemies(): HWMember[] {
        return this.guildEnemies;
    }

    getMembers(): HWMember[] {
        return this.guildMembers;
    }

    getLighthouse(): HWGuildWarFortification {
        //const indexes: number[] = [0, 4, 8];
        //return this._getFortification(indexes, 'heroes', 'Lighthouse');
        return this._getDefense('heroes', 'Lighthouse');
    }

    getBarracks(): HWGuildWarFortification {
        //const indexes: number[] = [1, 5, 6];
        //return this._getFortification(indexes, 'heroes', 'Barracks');
        return this._getDefense('heroes', 'Barracks');
    }

    getMageAcademy(): HWGuildWarFortification {
        //const indexes: number[] = [2, 3, 7];
        //return this._getFortification(indexes, 'heroes', 'Mage Academy');
        return this._getDefense('heroes', 'Mage Academy');
    }

    getFoundry(): HWGuildWarFortification {
        //const indexes: number[] = [9, 11, 12, 13];
        //return this._getFortification(indexes, 'heroes', 'Foundry');
        return this._getDefense('heroes', 'Foundry');
    }

    getCitadel(): HWGuildWarFortification {
        //const indexes: number[] = [10, 14, 15, 16, 17, 18, 19];
        //return this._getFortification(indexes, 'heroes', 'Citadel');
        return this._getDefense('heroes', 'Citadel');
    }

    getBridge(): HWGuildWarFortification {
        //const indexes: number[] = [0, 1, 2, 3];
        //return this._getFortification(indexes, 'titans', 'Bridge');
        return this._getDefense('titans', 'Bridge');
    }

    getGatesOfNature(): HWGuildWarFortification {
        //const indexes: number[] = [4, 9, 14, 19];
        //return this._getFortification(indexes, 'titans', 'Gates Of Nature');
        return this._getDefense('titans', 'Gates Of Nature');
    }

    getBastionOfFire(): HWGuildWarFortification {
        //const indexes: number[] = [5, 10, 15, 16];
        //return this._getFortification(indexes, 'titans', 'Bastion Of Fire');
        return this._getDefense('titans', 'Bastion Of Fire');
    }

    getBastionOfIce(): HWGuildWarFortification {
        //const indexes: number[] = [6, 11, 12, 17];
        //return this._getFortification(indexes, 'titans', 'Bastion Of Ice');
        return this._getDefense('titans', 'Bastion Of Ice');
    }

    getSpringOfElements(): HWGuildWarFortification {
        //const indexes: number[] = [7, 8, 13, 18];
        //return this._getFortification(indexes, 'titans', 'Spring Of Elements');
        return this._getDefense('titans', 'Spring Of Elements');
    }
}
