// 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 { ActivatedRoute } from '@angular/router';
import { AlertController, LoadingController } from '@ionic/angular';

import { ConfigService } from 'src/app/providers/config.service';
import { BizAvailabilityService } from 'src/app/providers/biz-availability.service';
import { WeeklyTemplate, AvailabilityException, OperatorSimple } from 'src/models/biz-appointments/availability.model';

interface DayConfig {
	dayOfWeek: number;
	label: string;
	active: boolean;
	startTime: string;
	endTime: string;
	breakStart: string;
	breakEnd: string;
}

@Component({
	standalone: false,
	selector: 'app-biz-availability',
	templateUrl: './biz-availability.page.html',
	styleUrls: ['./biz-availability.page.scss'],
})
export class BizAvailabilityPage implements OnInit {
	cmp_id: number = 0;
	operators: OperatorSimple[] = [];
	selectedOperatorId: number = 0; // 0 = Default Azienda

	// Template settimanale
	days: DayConfig[] = [];
	usingDefault: boolean = false;
	hasCustom: boolean = false;
	templateLoading: boolean = false;

	// Eccezioni
	exceptions: AvailabilityException[] = [];
	exceptionsLoading: boolean = false;

	// Form nuova eccezione
	showExceptionModal: boolean = false;
	newException: Partial<AvailabilityException> = {};

	private dayLabels = ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'];

	constructor(
		private route: ActivatedRoute,
		private alertController: AlertController,
		private loadingController: LoadingController,
		private configService: ConfigService,
		private availabilityService: BizAvailabilityService
	) {}

	ngOnInit(): void {
		this.cmp_id = Number(this.route.snapshot.paramMap.get('cmp_id') || this.route.parent?.snapshot.paramMap.get('cmp_id') || 0);
		this.initDays();
		this.loadOperators();
		this.loadTemplates();
	}

	initDays(): void {
		this.days = [];
		for (let i = 0; i < 7; i++) {
			this.days.push({
				dayOfWeek: i,
				label: this.dayLabels[i],
				active: i >= 1 && i <= 5, // Lun-Ven attivi
				startTime: '08:00',
				endTime: '17:00',
				breakStart: '12:00',
				breakEnd: '13:00',
			});
		}
	}

	loadOperators(): void {
		this.availabilityService.getOperators(this.cmp_id).subscribe({
			next: (data: any) => {
				this.operators = data || [];
			},
		});
	}

	onOperatorChange(): void {
		this.loadTemplates();
		this.loadExceptions();
	}

	loadTemplates(): void {
		this.templateLoading = true;
		const opId = this.selectedOperatorId || undefined;

		this.availabilityService.getWeeklyTemplates(this.cmp_id, opId).subscribe({
			next: (templates: any) => {
				const list: WeeklyTemplate[] = templates || [];
				if (list.length > 0) {
					this.applyTemplates(list);
					this.hasCustom = this.selectedOperatorId > 0;
					this.usingDefault = false;
				} else if (this.selectedOperatorId > 0) {
					// Nessun template personalizzato, carica default
					this.usingDefault = true;
					this.hasCustom = false;
					this.loadDefaultTemplates();
				} else {
					this.initDays();
					this.usingDefault = false;
					this.hasCustom = false;
				}
			},
			complete: () => {
				this.templateLoading = false;
			},
		});
	}

	private loadDefaultTemplates(): void {
		this.availabilityService.getWeeklyTemplates(this.cmp_id, 0).subscribe({
			next: (templates: any) => {
				const list: WeeklyTemplate[] = templates || [];
				if (list.length > 0) {
					this.applyTemplates(list);
				} else {
					this.initDays();
				}
			},
		});
	}

	private applyTemplates(templates: WeeklyTemplate[]): void {
		this.initDays();
		for (const t of templates) {
			const day = this.days.find((d) => d.dayOfWeek === t.wt_day_of_week);
			if (day) {
				day.active = t.wt_active;
				day.startTime = t.wt_start_time || '08:00';
				day.endTime = t.wt_end_time || '17:00';
				day.breakStart = t.wt_break_start || '12:00';
				day.breakEnd = t.wt_break_end || '13:00';
			}
		}
	}

	async saveTemplates(): Promise<void> {
		const loader = await this.loadingController.create({ message: 'Salvataggio...' });
		await loader.present();

		const opId = this.selectedOperatorId || 0;
		const templates: WeeklyTemplate[] = this.days.map((d) => ({
			wt_id: 0,
			wt_cmp_id: this.cmp_id,
			wt_operator_em_id: opId,
			wt_day_of_week: d.dayOfWeek,
			wt_start_time: d.startTime,
			wt_end_time: d.endTime,
			wt_break_start: d.breakStart,
			wt_break_end: d.breakEnd,
			wt_active: d.active,
		}));

		this.availabilityService.saveWeeklyTemplates(this.cmp_id, opId, templates).subscribe({
			next: () => {
				this.configService.presentToastSuccess('Template salvato');
				this.usingDefault = false;
				this.hasCustom = this.selectedOperatorId > 0;
			},
			error: () => {
				this.configService.presentToastError('Errore salvataggio');
			},
			complete: () => {
				loader.dismiss();
			},
		});
	}

	async resetToDefault(): Promise<void> {
		const alert = await this.alertController.create({
			header: 'Ripristina default',
			message: "Eliminare il template personalizzato e tornare al default dell'azienda?",
			buttons: [
				{ text: 'Annulla', role: 'cancel' },
				{
					text: 'Ripristina',
					handler: () => {
						// Salva template vuoto per cancellare il custom
						this.availabilityService.saveWeeklyTemplates(this.cmp_id, this.selectedOperatorId, []).subscribe({
							next: () => {
								this.configService.presentToastSuccess('Ripristinato al default');
								this.loadTemplates();
							},
						});
					},
				},
			],
		});
		await alert.present();
	}

	// --- Eccezioni ---

	loadExceptions(): void {
		if (!this.selectedOperatorId) return;
		this.exceptionsLoading = true;
		this.availabilityService.getExceptions(this.cmp_id, this.selectedOperatorId).subscribe({
			next: (data: any) => {
				this.exceptions = data || [];
			},
			complete: () => {
				this.exceptionsLoading = false;
			},
		});
	}

	openNewException(): void {
		this.newException = {
			ae_cmp_id: this.cmp_id,
			ae_operator_em_id: this.selectedOperatorId,
			ae_type: 'BLOCKED',
			ae_reason: '',
			ae_date: '',
			ae_start_time: null,
			ae_end_time: null,
		};
		this.showExceptionModal = true;
	}

	async saveException(): Promise<void> {
		if (!this.newException.ae_date) {
			this.configService.presentToastError('Seleziona una data');
			return;
		}

		// Formatta data
		const d = new Date(this.newException.ae_date);
		this.newException.ae_date = `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`;

		// Formatta orari per CUSTOM
		if (this.newException.ae_type === 'CUSTOM') {
			if (this.newException.ae_start_time) {
				const st = new Date(this.newException.ae_start_time);
				this.newException.ae_start_time = `${String(st.getHours()).padStart(2, '0')}:${String(st.getMinutes()).padStart(2, '0')}`;
			}
			if (this.newException.ae_end_time) {
				const et = new Date(this.newException.ae_end_time);
				this.newException.ae_end_time = `${String(et.getHours()).padStart(2, '0')}:${String(et.getMinutes()).padStart(2, '0')}`;
			}
		} else {
			this.newException.ae_start_time = null;
			this.newException.ae_end_time = null;
		}

		this.availabilityService.addException(this.newException).subscribe({
			next: () => {
				this.configService.presentToastSuccess('Eccezione aggiunta');
				this.showExceptionModal = false;
				this.loadExceptions();
			},
			error: () => {
				this.configService.presentToastError('Errore aggiunta eccezione');
			},
		});
	}

	async confirmDeleteException(exc: AvailabilityException): Promise<void> {
		const alert = await this.alertController.create({
			header: 'Elimina eccezione',
			message: `Eliminare l'eccezione del ${this.formatDate(exc.ae_date)}?`,
			buttons: [
				{ text: 'Annulla', role: 'cancel' },
				{
					text: 'Elimina',
					role: 'destructive',
					handler: () => {
						this.availabilityService.deleteException(exc.ae_id).subscribe({
							next: () => {
								this.configService.presentToastSuccess('Eccezione eliminata');
								this.loadExceptions();
							},
						});
					},
				},
			],
		});
		await alert.present();
	}

	formatDate(dateStr: string): string {
		if (!dateStr) return '-';
		const d = new Date(dateStr);
		return d.toLocaleDateString('it-IT', { day: '2-digit', month: '2-digit', year: 'numeric' });
	}
}
