// Questo file fa parte di MyTown.
// MyTown è software libero: puoi ridistribuirlo e/o modificarlo secondo
// i termini della GNU Affero General Public License come pubblicata dalla
// Free Software Foundation, versione 3.
// Distribuito senza ALCUNA GARANZIA; vedi la GNU AGPL v3 per i dettagli.
// Copyright (C) Kondor Consulting & Services S.r.l.
// SPDX-License-Identifier: AGPL-3.0-or-later

import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core';

import { ConfigService } from 'src/app/providers/config.service';
import { BizReviewsService } from 'src/app/providers/biz-reviews.service';
import { Review, ReviewCriteria, ReviewSource } from 'src/models/biz-appointments/review.model';

/**
 * CTA recensione riusabile: eligibilità + recensione esistente + modal stelle
 * multi-criterio, per qualsiasi transazione sorgente (source + sourceId).
 *
 * - mode 'section' (default): verifica subito l'eligibilità e mostra la sezione
 *   "La tua recensione" (recensione esistente oppure invito); non renderizza
 *   nulla se l'utente non può recensire. Per le pagine di dettaglio.
 * - mode 'button': mostra subito solo il bottone; l'eligibilità è verificata
 *   al click (toast se già recensito). Per le liste (es. ordini).
 */
@Component({
	selector: 'app-review-cta',
	templateUrl: './review-cta.component.html',
	styleUrls: ['./review-cta.component.scss'],
	standalone: false,
})
export class ReviewCtaComponent implements OnChanges {
	@Input() source!: ReviewSource;
	@Input() sourceId = 0;
	@Input() mode: 'section' | 'button' = 'section';
	@Input() prompt = 'Lascia una recensione verificata all\'impresa.';
	@Output() reviewed = new EventEmitter<void>();

	canReview = false;
	existingReview: Review | null = null;
	showModal = false;

	reviewCriteria = ReviewCriteria;
	stars = [1, 2, 3, 4, 5];
	ratings: { rev_rating_quality: number; rev_rating_service: number; rev_rating_price: number; rev_rating_timeliness: number } = {
		rev_rating_quality: 0,
		rev_rating_service: 0,
		rev_rating_price: 0,
		rev_rating_timeliness: 0,
	};
	title = '';
	text = '';

	constructor(
		private reviewsService: BizReviewsService,
		private configService: ConfigService,
	) {}

	ngOnChanges(changes: SimpleChanges): void {
		// Carico lo stato (eligibilità + recensione esistente) in entrambe le
		// modalità: anche in 'button' (liste) serve per mostrare lo stato
		// "Recensito" invece del pulsante quando l'utente ha già recensito.
		if (changes['sourceId'] || changes['source']) {
			this.loadState();
		}
	}

	private loadState(): void {
		this.canReview = false;
		this.existingReview = null;
		if (!this.source || !this.sourceId) return;
		this.reviewsService.getEligible(this.source, this.sourceId).subscribe({
			next: (res) => {
				this.canReview = !!res.eligible;
				this.existingReview = res.existing || null;
			},
		});
	}

	/** mode 'button': eligibilità on-demand, poi apre il modal o avvisa. */
	onButtonClick(): void {
		if (!this.source || !this.sourceId) return;
		this.reviewsService.getEligible(this.source, this.sourceId).subscribe({
			next: (res) => {
				if (res.existing) {
					this.configService.presentToastSuccess('Hai già recensito, grazie!');
					return;
				}
				if (!res.eligible) {
					this.configService.presentToastError('Recensione non disponibile');
					return;
				}
				this.openModal();
			},
		});
	}

	openModal(): void {
		this.ratings = { rev_rating_quality: 0, rev_rating_service: 0, rev_rating_price: 0, rev_rating_timeliness: 0 };
		this.title = '';
		this.text = '';
		this.showModal = true;
	}

	setRating(key: 'rev_rating_quality' | 'rev_rating_service' | 'rev_rating_price' | 'rev_rating_timeliness', value: number): void {
		this.ratings[key] = value;
	}

	get complete(): boolean {
		return this.ratings.rev_rating_quality > 0 && this.ratings.rev_rating_service > 0 && this.ratings.rev_rating_price > 0 && this.ratings.rev_rating_timeliness > 0;
	}

	submit(): void {
		if (!this.complete) return;
		const payload: Partial<Review> = {
			rev_source: this.source,
			rev_source_id: this.sourceId,
			...this.ratings,
			rev_title: this.title || null,
			rev_text: this.text || null,
		};
		this.reviewsService.addReview(payload).subscribe({
			next: () => {
				this.configService.presentToastSuccess('Recensione inviata, grazie!');
				this.showModal = false;
				this.canReview = false;
				// Ricarico lo stato in entrambe le modalità: così la lista ordini
				// (mode 'button') mostra subito lo stato "Recensito" con le stelle.
				this.loadState();
				this.reviewed.emit();
			},
			error: (err: any) => {
				const msg = err?.error?.message || err?.message || 'Errore invio recensione';
				this.configService.presentToastError(msg);
			},
		});
	}
}
