import { Injectable } from '@angular/core';
import { HttpParams } from '@angular/common/http';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

import { ApiService, UtilitiesService } from '@services';
import {
    HWGuildClan, HWWeekStat,
    HWMember, HWMemberList, HWMemberListConfig,
    HWMemberListFilters, HWMemberPageData, HWMemberStat
} from '@models';

import guildData from 'src/files-data/hw-guild-data.json'; // page Membres
import guildStatistics from 'src/files-data/hw-guild-statistics.json'; // page Overview -> Statistics
@Injectable({ providedIn: 'root' })
export class HWMemberService {
    private apiVersion = '/v3';
    constructor(
        private _apiService: ApiService,
        private _utilitiesService: UtilitiesService
    ) { }

    query(config: HWMemberListConfig): Observable<HWMemberList> {
        // Convert any filters over to Angular's URLSearchParams
        const params: HWMemberListFilters = {} as HWMemberListFilters;
        Object.assign(params, config.filters);
        return this._apiService
            .get(
                `${this.apiVersion}/members`,
                new HttpParams({ fromObject: <{
                    [param: string]: string | number | boolean | readonly (string | number | boolean)[];
                }>params })
            );
    }

    get(id: string): Observable<HWMemberPageData> {
        return this._apiService.get(`${this.apiVersion}/members/${id}`);
    }

    getAll(): Observable<Array<HWMember>> {
        return this._apiService.get(`${this.apiVersion}/members`).pipe(map(data => data.members));
    }

    create(member: HWMember): Observable<HWMember> {
        return this._apiService.post(`${this.apiVersion}/members/`, { member: member }).pipe(map(data => data.member));
    }

    update(member: HWMember): Observable<HWMember> {
        return this._apiService.put(`${this.apiVersion}/members/${member.id}`, { member: member }).pipe(map(data => data.member));
    }

    destroy(id: string): Observable<boolean> {
        return this._apiService.delete(`${this.apiVersion}/members/${id}`).pipe(map(data => data.deleted));
    }

    save(member: HWMember): Observable<HWMember> {
        // If we're updating an existing member
        if (member.id) {
            return this._apiService.put(`${this.apiVersion}/members/${member.id}`, { member: member }).pipe(map(data => data.member));
            // Otherwise, create a new member
        } else {
            return this._apiService.post(`${this.apiVersion}/members/`, { member: member }).pipe(map(data => data.member));
        }
    }
    
    loadMembers(clan: HWGuildClan): HWMember[] {
        const guildMembers: HWMember[] = [];
        const now = new Date();
        const oneDayInSec = (24 * 60 * 60);
        const daysToKick = parseInt(guildData.clan.daysToKick);
        for (const data of Object.entries(guildData.clan.members)) {
            const member: HWMember = {} as HWMember;
            Object.assign(member, data[1]);
            if (guildData.clan.warriors.indexOf(parseInt(member.id)) !== -1) {
                member.champion = true;
            } else {
                member.champion = false;
            }
            member.heroes = { power: 0, teams: []};
            member.titans = { power: 0, teams: []};
            guildMembers.push(member);
        }
        guildMembers.map((data: HWMember) => {
            const last = new Date((parseInt(data.lastLoginTime) * 1000));
            const exp = new Date(last.getTime() + ((daysToKick * oneDayInSec) * 1000));
            const diff = Math.floor(((exp.getTime() - now.getTime()) / 1000));
            const daysLeft = Math.floor((diff / oneDayInSec));
            let timeLeft = diff;
            if (daysLeft >= 1) {
                timeLeft = (diff - (daysLeft * oneDayInSec));
            }
            data.inactivity = {
                daysLeft: daysLeft,
                timeLeft: timeLeft,
                dropDelay: `${daysLeft}d, ${this._utilitiesService.secondsToDuration(timeLeft)}`,
                dropDate: Math.floor((exp.getTime() / 1000))
            };
            data.raids = [];
            data.raidsInfo = {
                variationAvg: 0,
                variationSum: 0
            };
            data.stat = {} as HWMemberStat;
            let index = guildData.membersStat.findIndex(stat => stat.userId === data.id);
            if (index !== -1) {
                // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
                const { userId, ...memberStatWithoutUserId } = guildData.membersStat[index] as any;
                Object.assign(data.stat, memberStatWithoutUserId);
            }
            index = guildStatistics.stat.findIndex(stat => stat.id === data.id);
            if (index !== -1) {
                // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unused-vars
                const { id, ...weekStatSource } = guildStatistics.stat[index] as any;
                const stat: HWWeekStat = {} as HWWeekStat;
                Object.assign(stat, weekStatSource);
                data.weekStat = stat;
                data.adventureSum = guildStatistics.stat[index].adventureStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
                data.clanGiftsSum = guildStatistics.stat[index].clanGifts.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
                data.clanWarSum = guildStatistics.stat[index].clanWarStat.reduce((accumulator, currentValue) => accumulator + currentValue, 0);
            } else {
                data.weekStat = {} as HWWeekStat;
                data.adventureSum = 0;
                data.clanGiftsSum = 0;
                data.clanWarSum = 0;
            }

            data.score = (data.stat.dungeonActivitySum + data.stat.activitySum + data.stat.prestigeSum);
            data.warGifts = (((clan.giftsCount / 2) * ((data.clanWarSum * 10) / 100)) / 20);
            data.scoreGifts = 0;
            data.rewards = 0;
            return data;
        });

        return guildMembers;
    }

}
