// 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 { CommonModule } from '@angular/common';
import { Component, ElementRef, EventEmitter, inject, Input, OnInit, Output, QueryList, ViewChildren } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { Router } from '@angular/router';
import { ActionSheetController, GestureController, IonicModule, Platform } from '@ionic/angular';
import { ServiceCard } from 'src/app/models/serviceCard.model';
import { LayoutService } from 'src/app/providers/layout.service';
import { CompaniesService } from 'src/app/providers/companies.service';
import { GeolocationService } from 'src/app/providers/geolocation.service';

@Component({
	selector: 'app-service-cards',
	templateUrl: './service-cards.component.html',
	styleUrls: ['./service-cards.component.scss'],
	imports: [CommonModule, FormsModule, IonicModule, ReactiveFormsModule],
})
export class ServiceCardsComponent implements OnInit {
	layoutService = inject(LayoutService);

	@Input() cards: ServiceCard[] = [];
	@Input() favoriteIds: Set<string> = new Set();
	@Input() distanceMap: Map<string, number> = new Map();
	/** true quando la griglia è seguita da altre sezioni: rimuove il padding di fondo (clearance tab bar) */
	@Input() inline = false;
	@Output() toggleFavorite = new EventEmitter<string>();
	@ViewChildren('cardElement', { read: ElementRef }) cardElements!: QueryList<ElementRef>;

	private pressTimer: any = null;
	private isLongPress = false;
	private actionSheetOpen = false;
	private touchStartTime = 0;
	private currentCard: ServiceCard | null = null;

	backgroundStyles = [
		// Original backgrounds
		{ name: 'Sunset', class: 'bg-gradient-sunset' },
		{ name: 'Ocean', class: 'bg-gradient-ocean' },
		{ name: 'Forest', class: 'bg-gradient-forest' },
		{ name: 'Cosmic', class: 'bg-gradient-cosmic' },
		{ name: 'Mint', class: 'bg-gradient-mint' },
		{ name: 'Fire', class: 'bg-gradient-fire' },
		{ name: 'Mesh Purple', class: 'bg-mesh-purple' },
		{ name: 'Geometric', class: 'bg-geometric' },
		{ name: 'Glass Morphism', class: 'bg-glass-morphism' },
		{ name: 'Neon Glow', class: 'bg-neon' },
		{ name: 'Dark Elegant', class: 'bg-dark-elegant' },
		{ name: 'Aurora', class: 'bg-aurora' },
		// New gradient backgrounds
		{ name: 'Nebula', class: 'bg-gradient-nebula' },
		{ name: 'Midnight', class: 'bg-gradient-midnight' },
		{ name: 'Galaxy', class: 'bg-gradient-galaxy' },
		{ name: 'Tropical', class: 'bg-gradient-tropical' },
		{ name: 'Berry', class: 'bg-gradient-berry' },
		{ name: 'Citrus', class: 'bg-gradient-citrus' },
		{ name: 'Lavender', class: 'bg-gradient-lavender' },
		{ name: 'Autumn', class: 'bg-gradient-autumn' },
		{ name: 'Mountain', class: 'bg-gradient-mountain' },
		{ name: 'Reef', class: 'bg-gradient-reef' },
		{ name: 'Cyber', class: 'bg-gradient-cyber' },
		{ name: 'Vaporwave', class: 'bg-gradient-vapor' },
		{ name: 'Synthwave', class: 'bg-gradient-synthwave' },
		{ name: 'Pulse', class: 'bg-gradient-pulse' },
		{ name: 'Wave', class: 'bg-gradient-wave' },
		{ name: 'Color Shift', class: 'bg-gradient-shift' },
		{ name: 'Gold Mesh', class: 'bg-mesh-gold' },
		{ name: 'Ruby Mesh', class: 'bg-mesh-ruby' },
		{ name: 'Aurora Borealis', class: 'bg-gradient-aurora-borealis' },
		{ name: 'Deep Sea', class: 'bg-gradient-deep-sea' },
		{ name: 'Volcanic', class: 'bg-gradient-volcanic' },
		{ name: 'Bronze', class: 'bg-gradient-bronze' },
		{ name: 'Steel', class: 'bg-gradient-steel' },
		{ name: 'Platinum', class: 'bg-gradient-platinum' },
		{ name: 'Dusk', class: 'bg-gradient-dusk' },
		{ name: 'Twilight', class: 'bg-gradient-twilight' },
		{ name: 'Mystic', class: 'bg-gradient-mystic' },
		{ name: 'Electric', class: 'bg-gradient-electric' },
		{ name: 'Plasma', class: 'bg-gradient-plasma' },
		{ name: 'Inferno', class: 'bg-gradient-inferno' },
		// Solid colors
		{ name: 'Rosso', class: 'bg-solid-red' },
		{ name: 'Rosa', class: 'bg-solid-rose' },
		{ name: 'Pink', class: 'bg-solid-pink' },
		{ name: 'Fucsia', class: 'bg-solid-fuchsia' },
		{ name: 'Porpora', class: 'bg-solid-purple' },
		{ name: 'Viola', class: 'bg-solid-violet' },
		{ name: 'Indaco', class: 'bg-solid-indigo' },
		{ name: 'Blu', class: 'bg-solid-blue' },
		{ name: 'Cielo', class: 'bg-solid-sky' },
		{ name: 'Ciano', class: 'bg-solid-cyan' },
		{ name: 'Teal', class: 'bg-solid-teal' },
		{ name: 'Smeraldo', class: 'bg-solid-emerald' },
		{ name: 'Verde', class: 'bg-solid-green' },
		{ name: 'Lime', class: 'bg-solid-lime' },
		{ name: 'Giallo', class: 'bg-solid-yellow' },
		{ name: 'Ambra', class: 'bg-solid-amber' },
		{ name: 'Arancione', class: 'bg-solid-orange' },
		{ name: 'Marrone', class: 'bg-solid-brown' },
		{ name: 'Grigio', class: 'bg-solid-gray' },
		{ name: 'Ardesia', class: 'bg-solid-slate' },
		{ name: 'Zinco', class: 'bg-solid-zinc' },
		{ name: 'Neutro', class: 'bg-solid-neutral' },
		{ name: 'Pietra', class: 'bg-solid-stone' },
		{ name: 'Nero', class: 'bg-solid-black' },
		{ name: 'Navy', class: 'bg-solid-navy' },
		{ name: 'Mezzanotte', class: 'bg-solid-midnight' },
		{ name: 'Foresta', class: 'bg-solid-forest' },
		{ name: 'Borgogna', class: 'bg-solid-maroon' },
		{ name: 'Cioccolato', class: 'bg-solid-chocolate' },
		{ name: 'Cremisi', class: 'bg-solid-crimson' },
	];

	constructor(private actionSheetController: ActionSheetController, private router: Router, private platform: Platform, private companiesService: CompaniesService, private geoService: GeolocationService) {}

	getCardDistanceLabel(card: ServiceCard): string | null {
		const d = this.distanceMap.get(this.getServiceUniqueId(card));
		return d !== undefined ? this.geoService.formatDistance(d) : null;
	}

	ngOnInit() {}

	ngAfterViewInit() {
		this.setupGestures();
		this.cardElements.changes.subscribe(() => {
			setTimeout(() => this.setupGestures(), 100);
		});
	}

	ngOnDestroy() {
		this.clearTimer();
	}

	setupGestures() {
		this.cardElements.forEach((element, index) => {
			const el = element.nativeElement;
			const card = this.cards[index];

			// Remove existing listeners first
			el.removeEventListener('touchstart', this.handleTouchStart);
			el.removeEventListener('touchend', this.handleTouchEnd);
			el.removeEventListener('touchmove', this.handleTouchMove);
			el.removeEventListener('contextmenu', this.handleContextMenu);

			// Add new listeners
			const touchStartHandler = (e: TouchEvent) => this.handleTouchStart(e, card);
			const touchEndHandler = (e: TouchEvent) => this.handleTouchEnd(e);
			const touchMoveHandler = () => this.handleTouchMove();
			const contextMenuHandler = (e: MouseEvent) => this.handleContextMenu(e, card);

			el.addEventListener('touchstart', touchStartHandler, { passive: true });
			el.addEventListener('touchend', touchEndHandler, { passive: true });
			el.addEventListener('touchmove', touchMoveHandler, { passive: true });
			el.addEventListener('contextmenu', contextMenuHandler);
		});
	}

	handleTouchStart = (event: TouchEvent, card: ServiceCard) => {
		// Clear any existing timer first
		this.clearTimer();

		// Don't start a new timer if action sheet is open or was recently closed
		if (this.actionSheetOpen) return;

		this.isLongPress = false;
		this.currentCard = card;
		this.touchStartTime = Date.now();

		this.pressTimer = setTimeout(() => {
			if (!this.actionSheetOpen && this.currentCard === card) {
				this.isLongPress = true;
				this.showActionSheet(card);
			}
		}, 500);
	};

	handleTouchEnd = (event: TouchEvent) => {
		const touchDuration = Date.now() - this.touchStartTime;
		const savedCard = this.currentCard;

		// Clear timer immediately
		this.clearTimer();

		// Navigate only if: quick tap, not long press, no action sheet, and we have a card
		if (!this.isLongPress && !this.actionSheetOpen && touchDuration < 500 && savedCard) {
			// Small delay to ensure action sheet isn't about to open
			setTimeout(() => {
				if (!this.actionSheetOpen && !this.isLongPress) {
					this.goToCompanyService(savedCard);
				}
			}, 50);
		}

		// Reset state
		this.isLongPress = false;
		this.currentCard = null;
		this.touchStartTime = 0;
	};

	handleTouchMove = () => {
		this.clearTimer();
		this.isLongPress = false;
		this.currentCard = null;
	};

	handleContextMenu = (event: MouseEvent, card: ServiceCard) => {
		event.preventDefault();
		event.stopPropagation();
		if (!this.actionSheetOpen) {
			this.showActionSheet(card);
		}
		return false;
	};

	handleCardClick(card: ServiceCard) {
		// For desktop clicks
		if (!this.platform.is('mobile') && !this.actionSheetOpen) {
			this.goToCompanyService(card);
		}
	}

	clearTimer() {
		if (this.pressTimer) {
			clearTimeout(this.pressTimer);
			this.pressTimer = null;
		}
	}

	async showActionSheet(card: ServiceCard) {
		// Double-check to prevent multiple sheets
		if (this.actionSheetOpen) return;

		// Clear any pending timers
		this.clearTimer();

		// Set flag immediately
		this.actionSheetOpen = true;
		this.isLongPress = true;

		// Haptic feedback
		if ('vibrate' in navigator) {
			navigator.vibrate(50);
		}

		try {
			const actionSheet = await this.actionSheetController.create({
				header: card.srv_name_view || 'Servizio',
				cssClass: 'service-action-sheet',
				buttons: [
					{
						text: this.isFavorite(card) ? 'Rimuovi dai preferiti' : 'Aggiungi ai preferiti',
						icon: this.isFavorite(card) ? 'heart' : 'heart-outline',
						handler: () => {
							this.toggleFavoriteStatus(card);
							return true;
						},
					},
					{
						text: 'Apri servizio',
						icon: 'open-outline',
						handler: () => {
							// Delay navigation slightly to ensure clean state
							setTimeout(() => {
								this.goToCompanyService(card);
							}, 100);
							return true;
						},
					},
					{
						text: 'Annulla',
						icon: 'close',
						role: 'cancel',
						handler: () => {
							return true;
						},
					},
				],
			});

			await actionSheet.present();

			// Handle dismiss and cleanup
			actionSheet.onDidDismiss().then(() => {
				// Reset state with a small delay to prevent immediate re-trigger
				setTimeout(() => {
					this.actionSheetOpen = false;
					this.isLongPress = false;
					this.currentCard = null;
				}, 100);
			});
		} catch (error) {
			console.error('Error showing action sheet:', error);
			this.actionSheetOpen = false;
			this.isLongPress = false;
		}
	}

	isFavorite(card: ServiceCard): boolean {
		const cardId = this.getServiceUniqueId(card);
		return this.favoriteIds.has(cardId);
	}

	toggleFavoriteStatus(card: ServiceCard) {
		const cardId = this.getServiceUniqueId(card);
		this.toggleFavorite.emit(cardId);
	}

	getServiceUniqueId(card: ServiceCard): string {
		return `${card.srv_id}_${card.company?.id || 0}`;
	}

	getImageOverlayStyles(card: ServiceCard) {
		if (!card.srv_background_image) return null;
		const opacity = card.srv_background_opacity ?? 0.5;
		return {
			'background-image': `url('${card.srv_background_image}')`,
			'background-size': 'cover',
			'background-position': 'center',
			opacity: opacity,
		};
	}

	goToCompanyService(_srv: ServiceCard) {
		// Don't navigate if action sheet is open or if we're in a long press
		if (this.actionSheetOpen || this.isLongPress) return;

		// Store the active service card for hero image display
		this.companiesService.activeServiceCard = _srv;

		let srv_link = _srv.srv_link;
		if (_srv.srv_link.includes('${cmp_id}')) {
			srv_link = srv_link.replace('${cmp_id}', _srv.company.id.toString());
		}

		if (_srv.srv_link.includes('${prt_id}')) {
			srv_link = srv_link.replace('${prt_id}', _srv.company.pt_id.toString());
		}

		this.layoutService.setPageConfig({
			title: _srv.srv_name_view,
			subtitle: _srv.srv_description ?? '',
			showBack: true,
		});

		// Navigate
		this.router.navigate([srv_link]);
	}
}
