// 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, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { Router, ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common';
import { BakekaService } from 'src/app/providers/bakeka.service';
import { ConfigService } from 'src/app/providers/config.service';
import { ReservationService } from 'src/app/providers/reservation.service';

@Component({
	selector: 'app-reservation',
	templateUrl: './reservation.component.html',
	styleUrls: ['./reservation.component.scss'],
	standalone: false,
})
export class ReservationComponent implements OnInit {
	constructor(private router: Router, private activatedRoute: ActivatedRoute, private location: Location, private bakekaService: BakekaService, private configService: ConfigService, private reservationService: ReservationService) {}

	// variabili
	bakeka: any = {};
	cmp_id = 0;
	tabDay = false; // bool per attivazione html
	tickets = 1; // biglietti che si vogliono ordinare (minimo 1)
	rangeDate: number[] = []; // date disponibili
	filteredSlots: any[] = []; // slot filtrati per data
	checkslot = false;

	timeSlots: any[] = [];
	calendarMonth = '';
	totalCapacity = 0;
	selectedSlot: any;
	selectedDate: any;
	/** 'YYYY-MM-DD|slotId' → posti occupati */
	slotOccupancyMap = new Map<string, number>();
	/** YYYY-MM-DD → { occupied, total } */
	dayCapacityMap = new Map<string, { occupied: number; total: number }>();
	/** Array calcolato per ion-datetime [highlightedDates] */
	highlightedDatesArray: { date: string; textColor: string; backgroundColor: string }[] = [];

	paramsSubscription?: Subscription;
	ngOnInit() {
		this.paramsSubscription = this.activatedRoute.params.subscribe((params) => {
			if (params['cmp_id']) this.cmp_id = +params['cmp_id'];
			if (+params['id']) {
				this.bakeka.bk_id = +params['id'];
			} else {
				this.bakeka.bk_id = -1;
				alert('impossibile effettuare la prenotazione');
			}
		});
	}

	ionViewWillEnter() {
		this.getEvent();
	}

	getEvent() {
		this.bakekaService.getPost(this.cmp_id, this.bakeka.bk_id).subscribe((res) => {
			this.bakeka = res;
			this.bakeka.bk_date = this.configService.formatDateToString(this.configService.formatDate(this.bakeka.bk_date));
			this.bakeka.bk_date_to = this.configService.formatDateToString(this.configService.formatDate(this.bakeka.bk_date_to));
			this.bakeka.slots.forEach((slot: any) => {
				let day: number = parseInt(slot.bks_day[2], 10);
				this.rangeDate.push(day);
				this.totalCapacity += slot.bks_tk_ava;
			});
			const today = new Date();
			this.calendarMonth = `${today.getFullYear()}-${String(today.getMonth() + 1).padStart(2, '0')}`;
			this.recomputeAvailability();
		});
	}

	// azioni su ticket, calendario e slot
	getSlotOccupancyPercent(slot: any): number {
		if (slot.bks_tk_amount <= 0) return 0;
		return Math.min(100, Math.round((this.getSlotOccupied(slot) / slot.bks_tk_amount) * 100));
	}

	getSlotOccupied(slot: any): number {
		// tk occupati, quindi tk_totali - tk_disponibili
		return Math.max(0, slot.bks_tk_amount - slot.bks_tk_ava);
	}

	getSlotFree(slot: any): number {
		return slot.bks_tk_ava;
	}

	canFitInSlot(slot: any): boolean {
		const guests = this.tickets || 1;
		return this.getSlotFree(slot) >= guests;
	}

	onSlotSelected(slot: any) {
		this.selectedSlot = slot;
		this.checkslot = true;
	}

	onDaySelected(event: any) {
		if (this.tickets <= 0) {
			alert('Inserisci il numero dei biglietti che vuoi acquistare.');
		}
		this.filteredSlots = [];
		let seldate = event.detail.value;
		for (let i = 0; i < this.bakeka.slots.length; i++) {
			let date = this.configService.formatDateToString(this.configService.formatDate(this.bakeka.slots[i].bks_day));
			if (seldate.substring(0, 10) == date) {
				this.filteredSlots.push(this.bakeka.slots[i]);
			}
		}
		this.tabDay = true;
	}

	private recomputeAvailability() {
		this.dayCapacityMap.clear();
		this.slotOccupancyMap.clear();
		if (this.totalCapacity <= 0) {
			this.highlightedDatesArray = [];
			return;
		}
		const dayOccupied = new Map<string, number>();
		let slotsTotalCapacity = 0;
		for (const b of this.bakeka.slots) {
			slotsTotalCapacity += b.bks_tk_amount /** Math.max(1, this.timeSlots.length)*/;
			const date = this.configService._normDate(b.bks_day);
			if (!date) continue;
			const guests = this.getSlotOccupied(b) || 0;
			dayOccupied.set(date, (dayOccupied.get(date) || 0) + guests);
			if (b.bks_id) {
				const key = `${date}|${b.bks_id}`;
				this.slotOccupancyMap.set(key, (this.slotOccupancyMap.get(key) || 0) + guests);
			}
		}
		for (const [date, occupied] of dayOccupied.entries()) {
			this.dayCapacityMap.set(date, { occupied, total: slotsTotalCapacity });
		}
		this._rebuildHighlightedDates();
	}

	private _rebuildHighlightedDates() {
		if (!this.calendarMonth || this.totalCapacity <= 0) {
			this.highlightedDatesArray = [];
			return;
		}
		const [y, m] = this.calendarMonth.split('-').map(Number);

		const todayStr = this.selectedDate;
		const out: { date: string; textColor: string; backgroundColor: string }[] = [];
		for (let i = 0; i < this.bakeka.slots.length; i++) {
			let slotsTotal = this.bakeka.slots[i].bks_tk_amount;
			const dateStr = `${y}-${String(m).padStart(2, '0')}-${String(this.rangeDate[i]).padStart(2, '0')}`;
			if (dateStr < todayStr) continue;
			const info = this.dayCapacityMap.get(dateStr);
			const pct = info && slotsTotal > 0 ? info.occupied / slotsTotal : 0;
			if (pct >= 0.85) out.push({ date: dateStr, textColor: '#fff', backgroundColor: '#e74c3c' });
			else if (pct >= 0.5) out.push({ date: dateStr, textColor: '#333', backgroundColor: '#f1c40f' });
			else out.push({ date: dateStr, textColor: '#fff', backgroundColor: '#27ae60' });
		}
		this.highlightedDatesArray = out;
	}

	// aggiungi prenotazione

	addtoCart() {
		// La prenotazione (aggiunta al carrello) richiede l'accesso: i non registrati
		// vengono portati al login.
		if (!this.configService.isLogged()) {
			this.router.navigate(['/login']);
			return;
		}
		let res: any = {};
		res.rsv_bk_id = this.bakeka.bk_id;
		res.rsv_bks_id = this.selectedSlot.bks_id;
		res.rsv_tk_amount = this.tickets;
		res.price = this.selectedSlot.bks_tk_price;
		res.tk = this.tickets;
		res.cmp_id = this.cmp_id;
		this.reservationService.reservation_add(res).subscribe(() => {});
	}

	// INDIRIZZAMENTI

	goBack() {
		this.location.back();
	}
}
