import core from '../chat/core';
import { Character as CharacterFChatInf } from '../fchat';
import { Character as ComplexCharacter } from '../site/character_page/interfaces';
import { Matcher } from './matcher';
import { AdCache } from './ad-cache';
import { ProfileCacheQueueEntry } from './cache-manager';
import { TagId } from './matcher-types';


export class CharacterProfiler {
    static readonly ADVERTISEMENT_RECENT_RANGE = 22 * 60 * 1000;
    static readonly ADVERTISEMENT_POTENTIAL_RAGE = 50 * 60 * 1000;

    protected adCache: AdCache;
    protected me: ComplexCharacter;

    constructor(me: ComplexCharacter, adCache: AdCache) {
        this.me = me;
        this.adCache = adCache;
    }

    calculateInterestScoreForQueueEntry(entry: ProfileCacheQueueEntry): number {
        const c = core.characters.get(entry.name);

        if (!c)
            return 0;

        const genderScore = this.getInterestScoreForGender(this.me, c);
        const statusScore = this.getInterestScoreForStatus(c);
        const adScore = (genderScore > 0) ? this.getLastAdvertisementStatus(c) : 0;
        const friendlyScore = this.getInterestScoreForFriendlies(c);

        // tslint:disable-next-line: number-literal-format binary-expression-operand-order
        const score = ((1.0 * genderScore) + (1.0 * statusScore) + (1.0 * adScore) + (1.0 * friendlyScore));

        // tslint:disable-next-line: number-literal-format binary-expression-operand-order
        return (c.status === 'looking') ? score + 10.0 : score;
    }


    getInterestScoreForFriendlies(c: CharacterFChatInf.Character): number {
        if(c.isFriend)
            return 1;

        if(c.isBookmarked)
            return 0.5;

        if(c.isIgnored)
            return -1;

        return 0;
    }


    getInterestScoreForGender(me: ComplexCharacter, c: CharacterFChatInf.Character): number {
        const g = Matcher.strToGender(c.gender);

        if (g === null) {
            return 0;
        }

        const myGender = Matcher.getTagValueList(TagId.Gender, me.character);
        const myOrientation = Matcher.getTagValueList(TagId.Orientation, me.character);
        const score = Matcher.scoreOrientationByGender(myGender, myOrientation, g);

        return score.score;
    }


    getInterestScoreForStatus(c: CharacterFChatInf.Character): number {
        if ((c.status === 'offline') || (c.status === 'away') || (c.status === 'busy') || (c.status === 'dnd'))
            return -0.5;

        if (c.status === 'looking')
            return 0.5;

        return 0;
    }


    getLastAdvertisementStatus(c: CharacterFChatInf.Character): number {
        const ads = this.adCache.get(c.name);

        if (!ads)
            return 0;

        const lastPost = ads.getDateLastPosted();

        if (lastPost === null)
            return 0;

        const delta = Date.now() - lastPost.getTime();

        if (delta < CharacterProfiler.ADVERTISEMENT_RECENT_RANGE)
            return 1;

        if (delta < CharacterProfiler.ADVERTISEMENT_POTENTIAL_RAGE)
            return 0.5;

        return -0.5; // has been advertising, but not recently, so likely busy
    }
}