import { Injectable, inject } from '@angular/core';
import { BehaviorSubject, Observable, Subject } from 'rxjs';
import { Challenge } from '../models/challenge.models';

/**
 * Service to manage challenge events via WebSocket
 * Listens for incoming challenges and emits them to subscribers
 */
@Injectable({ providedIn: 'root' })
export class ChallengeEventService {
    private readonly incomingChallenges$ = new BehaviorSubject<Challenge[]>([]);
    private readonly challengeReceived$ = new Subject<Challenge>();
    private readonly challengeAccepted$ = new Subject<Challenge>();
    private readonly challengeDeclined$ = new Subject<Challenge>();

    getIncomingChallenges$(): Observable<Challenge[]> {
        return this.incomingChallenges$.asObservable();
    }

    getChallengeReceived$(): Observable<Challenge> {
        return this.challengeReceived$.asObservable();
    }

    getChallengeAccepted$(): Observable<Challenge> {
        return this.challengeAccepted$.asObservable();
    }

    getChallengeDeclined$(): Observable<Challenge> {
        return this.challengeDeclined$.asObservable();
    }

    /**
     * Called when a new challenge is received via WebSocket
     */
    onChallengeReceived(challenge: Challenge): void {
        const current = this.incomingChallenges$.value;
        this.incomingChallenges$.next([...current, challenge]);
        this.challengeReceived$.next(challenge);
    }

    /**
     * Called when a challenge is accepted
     */
    onChallengeAccepted(challenge: Challenge): void {
        const current = this.incomingChallenges$.value;
        this.incomingChallenges$.next(current.filter(c => c.id !== challenge.id));
        this.challengeAccepted$.next(challenge);
    }

    /**
     * Called when a challenge is declined or expires
     */
    onChallengeRemoved(challengeId: string): void {
        const current = this.incomingChallenges$.value;
        this.incomingChallenges$.next(current.filter(c => c.id !== challengeId));
    }

    /**
     * Remove a challenge from the incoming list
     */
    removeChallenge(challengeId: string): void {
        this.onChallengeRemoved(challengeId);
    }

    /**
     * Replace the full incoming list (used by HTTP polling)
     */
    setIncomingChallenges(challenges: Challenge[]): void {
        this.incomingChallenges$.next(challenges);
    }

    /**
     * Clear all incoming challenges (used on logout)
     */
    clear(): void {
        this.incomingChallenges$.next([]);
    }
}
