import { Component, Input, Output, EventEmitter, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router } from '@angular/router';
import { Challenge } from '../../models/challenge.models';
import { ChallengeService } from '../../services/challenge.service';
import { finalize } from 'rxjs';
import { getErrorMessage } from '../../core/http/error-message.util';

@Component({
    selector: 'app-challenge-notification',
    standalone: true,
    imports: [CommonModule],
    templateUrl: './challenge-notification.component.html',
    styleUrls: ['./challenge-notification.component.css']
})
export class ChallengeNotificationComponent {
    @Input() challenge!: Challenge;
    @Output() accept = new EventEmitter<Challenge>();
    @Output() decline = new EventEmitter<Challenge>();
    @Output() close = new EventEmitter<void>();

    private readonly challengeService = inject(ChallengeService);
    private readonly router = inject(Router);

    acceptingChallenge = false;
    decliningChallenge = false;
    errorMessage = '';

    onAccept(): void {
        if (this.acceptingChallenge || this.decliningChallenge) {
            return;
        }

        this.acceptingChallenge = true;
        this.errorMessage = '';

        this.challengeService.acceptChallenge(this.challenge.id)
            .pipe(finalize(() => (this.acceptingChallenge = false)))
            .subscribe({
                next: (acceptedChallenge) => {
                    this.accept.emit(acceptedChallenge);
                    if (acceptedChallenge.gameId) {
                        void this.router.navigate(['/game', acceptedChallenge.gameId]);
                    } else {
                        this.errorMessage = 'Challenge accepted, but no game was created.';
                    }
                },
                error: (error) => {
                    this.errorMessage = getErrorMessage(error, 'Failed to accept challenge');
                }
            });
    }

    onDecline(): void {
        if (this.acceptingChallenge || this.decliningChallenge) {
            return;
        }

        this.decliningChallenge = true;
        this.errorMessage = '';

        this.challengeService.declineChallenge(this.challenge.id, { reason: 'generic' })
            .pipe(finalize(() => (this.decliningChallenge = false)))
            .subscribe({
                next: () => {
                    this.decline.emit(this.challenge);
                },
                error: (error) => {
                    this.errorMessage = getErrorMessage(error, 'Failed to decline challenge');
                }
            });
    }

    onClose(): void {
        this.close.emit();
    }

    getTimeControlDisplay(): string {
        const { limit, increment } = this.challenge.timeControl;
        if (!limit || !increment) {
            return 'Unlimited';
        }
        const minutes = Math.floor(limit / 60);
        return `${minutes}+${increment}`;
    }

    getCreatedByDisplay(): string {
        return this.challenge.challenger.name;
    }

    getExpirationInfo(): string {
        const expiresAt = new Date(this.challenge.expiresAt);
        const now = new Date();
        const diffMs = expiresAt.getTime() - now.getTime();

        if (diffMs <= 0) {
            return 'Expired';
        }

        const minutes = Math.floor(diffMs / 60000);
        if (minutes > 60) {
            const hours = Math.floor(minutes / 60);
            return `Expires in ${hours}h`;
        }

        return `Expires in ${minutes}m`;
    }
}
