// 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, inject, OnInit } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { AlertController, IonicModule } from '@ionic/angular';
import { Capacitor } from '@capacitor/core';
import { User } from 'src/app/models/user.model';
import { Role } from 'src/app/models/role.model';
import { Router } from '@angular/router';
import { ConfigService } from 'src/app/providers/config.service';
import { LoginService } from 'src/app/providers/login.service';
import { LayoutService } from 'src/app/providers/layout.service';
import { PushPermissionStatus, PushService } from 'src/app/providers/push.service';
import { GeolocationService } from 'src/app/providers/geolocation.service';
import { ContactsService } from 'src/app/providers/contacts.service';
import { CompaniesService } from 'src/app/providers/companies.service';

type RoleWithSource = Role & { rl_source: 'portal' | 'company' };

@Component({
	selector: 'app-user-profile',
	standalone: true,
	imports: [CommonModule, FormsModule, IonicModule],
	templateUrl: './profilo.page.html',
	styleUrls: ['./profilo.page.scss'],
})
export class ProfiloComponent implements OnInit {
	constructor(
		private router: Router,
		public configService: ConfigService,
		private loginService: LoginService,
		public pushService: PushService,
		public geoService: GeolocationService,
		public contactsService: ContactsService,
		private alertController: AlertController,
		private companiesService: CompaniesService,
	) {}

	layoutService = inject(LayoutService);

	user!: User;
	avatarUploading = false;
	isEditMode = false;
	editableUser: User = { ...this.user };
	assignedRoles: RoleWithSource[] = [];
	portalRoles: RoleWithSource[] = [];
	companyRoles: RoleWithSource[] = [];
	selectedSegment = 'profile';

	// Push notifications
	isNativePlatform = Capacitor.getPlatform() !== 'web';
	pushSystemStatus: PushPermissionStatus = 'prompt';
	pushSystemLoading = false;
	pushLocalEnabled = true;
	pushToggleLoading = false;

	// Notification preferences
	emailNotificationsEnabled = true;
	smsNotificationsEnabled = false;
	preferencesLoading = false;

	ionViewWillEnter() {
		this.layoutService.setPageConfig({
			title: 'Profilo utente',
			showBack: false,
		});
		if (this.isNativePlatform) {
			this.refreshPushStatus();
			this.contactsService.loadIfPermitted();
		}
	}

	ngOnInit() {
		this.getUser();
		this.getUserRoles();
		this.getCompanyRoles();
	}

	getUser() {
		this.loginService.getUser(this.configService.getUserID()).subscribe({
			next: (user: User) => {
				if (!user) return;
				// Solo i data-URL sono avatar validi: il DB legacy conteneva path tipo
				// '/avatar/default.svg' (file inesistente) → immagine rotta
				user.avatar = (user.avatar || '').startsWith('data:image') ? user.avatar! : '';
				this.user = user;
				this.editableUser = { ...this.user };
				this.emailNotificationsEnabled = user.usr_email_notifications ?? true;
				this.smsNotificationsEnabled = user.usr_sms_notifications ?? false;
				// Allinea l'avatar nel currentUser locale (usato da header/menu) al valore dal backend
				if (user.avatar !== this.configService.getUserAvatar()) {
					this.configService.setUserAvatar(user.avatar);
				}
			},
		});
	}

	hasPhone(): boolean {
		return !!this.user?.usr_phone?.trim();
	}

	async saveNotificationPreferences() {
		this.preferencesLoading = true;
		this.loginService.saveNotificationPreferences(this.configService.getUserID(), this.emailNotificationsEnabled, this.smsNotificationsEnabled).subscribe({
			next: () => {
				this.preferencesLoading = false;
			},
			error: () => {
				this.preferencesLoading = false;
			},
		});
	}

	getUserRoles() {
		this.loginService.getRuoliUser(this.configService.getUserID()).subscribe({
			next: (roles: Role[]) => {
				console.log('[Profilo] portal roles raw:', roles);
				this.portalRoles = (roles || []).filter((r) => r.rl_isChecked).map((r) => ({ ...r, rl_source: 'portal' as const }));
				this.mergeRoles();
			},
		});
	}

	getCompanyRoles() {
		this.companiesService.getAssignedCompanyRoles(this.configService.getUserID()).subscribe({
			next: (roles: Role[]) => {
				console.log('[Profilo] company roles raw:', roles);
				this.companyRoles = (roles || []).map((r) => ({
					...r,
					rl_isChecked: true,
					rl_source: 'company' as const,
				}));
				this.mergeRoles();
			},
			error: (err) => {
				console.warn('[Profilo] company roles endpoint error:', err);
				this.companyRoles = [];
				this.mergeRoles();
			},
		});
	}

	private mergeRoles() {
		this.assignedRoles = [...this.portalRoles, ...this.companyRoles];
	}

	// ── Push notifications ──────────────────────────────────────

	async refreshPushStatus() {
		this.pushSystemLoading = true;
		this.pushSystemStatus = await this.pushService.checkPermissionStatus();
		this.pushLocalEnabled = !this.pushService.isDisabledLocally();
		this.pushSystemLoading = false;
	}

	async onRequestSystemPermission() {
		this.pushSystemLoading = true;
		const granted = await this.pushService.requestSystemPermission();
		if (granted) {
			this.pushSystemStatus = 'granted';
			this.pushLocalEnabled = true;
		} else {
			// Se denied, guida l'utente nelle impostazioni di sistema
			await this.pushService.openSystemNotificationSettings();
			// Rilegge stato dopo il ritorno
			this.pushSystemStatus = await this.pushService.checkPermissionStatus();
		}
		this.pushSystemLoading = false;
	}

	async onOpenSystemSettings() {
		await this.pushService.openSystemNotificationSettings();
		// Aspetta un po' e rilegge lo stato (l'utente potrebbe aver modificato)
		setTimeout(async () => {
			this.pushSystemStatus = await this.pushService.checkPermissionStatus();
		}, 1500);
	}

	async onTogglePushLocal(enabled: boolean) {
		this.pushToggleLoading = true;
		try {
			if (enabled) {
				await this.pushService.enablePushLocally();
			} else {
				await this.pushService.disablePushLocally();
			}
		} finally {
			this.pushToggleLoading = false;
		}
	}

	// ── Geolocation ─────────────────────────────────────────────

	geoLoading = false;

	get geoStatus() {
		return this.geoService.getStatus();
	}
	get geoPosition() {
		return this.geoService.getPosition();
	}

	async onEnableGeolocation() {
		this.geoLoading = true;
		try {
			await this.geoService.requestPosition();
		} catch {}
		this.geoLoading = false;
	}

	onDisableGeolocation() {
		this.geoService.clearPosition();
	}

	async onOpenGeoSettings() {
		await this.geoService.openSystemLocationSettings();
	}

	// ── Rubrica (contacts) ────────────────────────────────────────

	contactsLoading = false;
	/** Observable reattivo: aggiorna la UI anche quando il permesso cambia in background */
	contactsStatus$ = this.contactsService.status$;

	async onEnableContacts() {
		this.contactsLoading = true;
		await this.contactsService.requestAndLoad();
		this.contactsLoading = false;
	}

	onDisableContacts() {
		this.contactsService.disableContacts();
	}

	async onOpenContactsSettings() {
		await this.contactsService.openSystemSettings();
	}

	// ── Helpers ─────────────────────────────────────────────────

	toggleEditMode() {
		if (this.isEditMode) {
			this.user = { ...this.editableUser };
		} else {
			this.editableUser = { ...this.user };
		}
		this.isEditMode = !this.isEditMode;
	}

	cancelEdit() {
		this.editableUser = { ...this.user };
		this.isEditMode = false;
	}

	getRoleColor(roleType: string): string {
		switch ((roleType || '').toLowerCase()) {
			case 'admin':
				return '#c62828';
			case 'developer':
				return '#0F75BB';
			case 'manager':
				return '#e07b00';
			case 'user':
				return '#198754';
			default:
				return '#5f5f5f';
		}
	}

	getRoleIconBg(roleType: string): string {
		switch ((roleType || '').toLowerCase()) {
			case 'admin':
				return '#fce4ec';
			case 'developer':
				return '#e0f0fb';
			case 'manager':
				return '#fff3e0';
			case 'user':
				return '#e8f7ee';
			default:
				return '#f0f0f0';
		}
	}

	getRoleIcon(roleType: string): string {
		switch ((roleType || '').toLowerCase()) {
			case 'admin':
				return 'shield-outline';
			case 'developer':
				return 'code-slash-outline';
			case 'manager':
				return 'briefcase-outline';
			case 'user':
				return 'person-outline';
			default:
				return 'ellipse-outline';
		}
	}

	getPortalStatusColor(isActive: boolean): string {
		return isActive ? 'success' : 'medium';
	}

	getActiveRolesCount(): number {
		return this.assignedRoles?.filter((role) => role.rl_isChecked).length || 0;
	}

	getUserInitials(): string {
		return this.configService.getUsernameInitials();
	}

	getAvatarColor(): string {
		return this.configService.getColorFromDisplayName();
	}

	// ── Immagine profilo ────────────────────────────────────────
	onAvatarSelected(event: Event) {
		const input = event.target as HTMLInputElement;
		if (!input.files || input.files.length === 0) return;
		const file = input.files[0];
		input.value = ''; // consente di riselezionare lo stesso file
		this.resizeSquare(file).then((dataUrl) => this.saveAvatar(dataUrl));
	}

	removeAvatar() {
		this.saveAvatar('');
	}

	private saveAvatar(dataUrl: string) {
		this.avatarUploading = true;
		this.loginService.updateAvatar(dataUrl).subscribe({
			next: () => {
				this.avatarUploading = false;
				this.user.avatar = dataUrl;
				this.configService.setUserAvatar(dataUrl);
				this.configService.presentToastSuccess(dataUrl ? 'Immagine profilo aggiornata' : 'Immagine profilo rimossa');
			},
			error: () => {
				this.avatarUploading = false;
				this.configService.presentToastError("Errore durante il salvataggio dell'immagine profilo");
			},
		});
	}

	// Ridimensiona e ritaglia l'immagine in un quadrato 256x256 JPEG, restituendo un data-URL base64.
	private resizeSquare(file: File): Promise<string> {
		return new Promise((resolve, reject) => {
			const img = new Image();
			const url = URL.createObjectURL(file);
			img.onload = () => {
				const size = 256;
				const side = Math.min(img.width, img.height);
				const sx = (img.width - side) / 2;
				const sy = (img.height - side) / 2;
				const canvas = document.createElement('canvas');
				canvas.width = size;
				canvas.height = size;
				canvas.getContext('2d')!.drawImage(img, sx, sy, side, side, 0, 0, size, size);
				URL.revokeObjectURL(url);
				resolve(canvas.toDataURL('image/jpeg', 0.85));
			};
			img.onerror = (e) => {
				URL.revokeObjectURL(url);
				reject(e);
			};
			img.src = url;
		});
	}

	segmentChanged(event: any) {
		this.selectedSegment = event.detail.value;
	}

	// ── Logout ──────────────────────────────────────────────────

	logoutLoading = false;

	async confirmLogout() {
		const alert = await this.alertController.create({
			header: 'Disconnessione',
			message: "Vuoi uscire dall'account? Dovrai inserire di nuovo le credenziali al prossimo accesso.",
			cssClass: 'logout-alert',
			buttons: [
				{
					text: 'Annulla',
					role: 'cancel',
					cssClass: 'logout-alert-cancel',
				},
				{
					text: 'Esci',
					role: 'destructive',
					cssClass: 'logout-alert-confirm',
					handler: () => this.doLogout(),
				},
			],
		});
		await alert.present();
	}

	private doLogout() {
		this.logoutLoading = true;
		this.configService.logout();
		this.router.navigate(['/login']);
	}
}
