// 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 } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { ConfigService } from '../../../providers/config.service';
import { LayoutService } from '../../../providers/layout.service';
import { WorkflowService } from '../../../providers/workflow.service';
import { WfInstance, WfJob, WfStartable } from '../../../models/workflow.model';

type Segment = 'inizia' | 'storico' | 'attivita';

@Component({
	selector: 'app-workflow-list',
	templateUrl: './workflow-list.page.html',
	styleUrls: ['./workflow-list.page.scss'],
	standalone: false,
})
export class WorkflowListPage {
	cmp_id = 0;
	prt_id = 0;

	segment: Segment = 'inizia';
	search = '';
	private searchTimer: any;
	loading = false;

	// Tab 1 — attività che posso iniziare (activity/list_by_user)
	startables: WfStartable[] = [];
	// Tab 2 — storico istanze
	instances: WfInstance[] = [];
	// Tab 3 — le mie attività (job aperti, già filtrati per ruolo dal backend)
	jobs: WfJob[] = [];

	constructor(
		private route: ActivatedRoute,
		private router: Router,
		private config: ConfigService,
		public layout: LayoutService,
		private wf: WorkflowService,
	) {}

	ionViewWillEnter() {
		this.resolveIds();
		this.layout.setPageConfig({ title: 'Workflow', showBack: true, backButtonHref: '/servizi' });
		this.load();
	}

	private resolveIds() {
		let r: ActivatedRoute | null = this.route;
		while (r) {
			const pm = r.snapshot.paramMap;
			if (pm.get('cmp_id')) this.cmp_id = +(pm.get('cmp_id') as string);
			if (pm.get('prt_id')) this.prt_id = +(pm.get('prt_id') as string);
			r = r.parent;
		}
	}

	segmentChanged() {
		// i dati dei tre tab sono già caricati: niente reload al cambio tab
	}

	onSearch() {
		clearTimeout(this.searchTimer);
		this.searchTimer = setTimeout(() => this.load(), 300);
	}

	/** Carica i tre elenchi insieme, così i badge di conteggio sono sempre aggiornati. */
	load(ev?: any) {
		this.loading = true;
		let pending = 3;
		let errored = false;
		const done = () => {
			if (--pending <= 0) {
				this.loading = false;
				ev?.target?.complete();
				if (errored) this.config.presentToastError('Errore nel caricamento del workflow');
			}
		};

		this.wf.getStartableActivities(this.cmp_id).subscribe({
			next: (rows) => {
				this.startables = rows || [];
				done();
			},
			error: () => {
				errored = true;
				done();
			},
		});

		this.wf.getInstanceList(this.cmp_id, this.search || '', 'wfin_dateins DESC', 1, 50).subscribe({
			next: (rows) => {
				this.instances = rows || [];
				done();
			},
			error: () => {
				errored = true;
				done();
			},
		});

		this.wf.getJobList(this.cmp_id, this.search || '', 'wfj_dateins DESC', 1, 50).subscribe({
			next: (rows) => {
				this.jobs = (rows || []).filter((j) => j.wfj_state === 0 || j.wfj_state == null);
				this.decorate(this.jobs);
				done();
			},
			error: () => {
				errored = true;
				done();
			},
		});
	}

	/** Aggiunge un'etichetta leggibile a ciascun job dal parse di wfj_data. */
	private decorate(jobs: WfJob[]) {
		for (const j of jobs) {
			const { activity } = this.wf.parseJob(j);
			j.activity = activity || undefined;
		}
	}

	jobLabel(j: WfJob): string {
		return j.activity?.label || j.wfj_description || j.wfj_detail || 'Attività';
	}

	instanceTitle(i: WfInstance): string {
		return i.wf_name || i.wfin_description || ('Istanza #' + (i.wfin_instance ?? i.wfin_id));
	}

	private instanceId(i: WfInstance): string {
		return String(i.wfin_instance ?? i.wfin_id ?? '');
	}

	// ─── navigazione ───────────────────────────────────────────────

	/** Tab 1: avvia un nuovo workflow (modalità start: wf_id, wf_state=0). */
	startActivity(a: WfStartable) {
		if (!a?.wf_id) return;
		this.router.navigate(['start', a.wf_id], { relativeTo: this.route });
	}

	/** Tab 3: riprende un job aperto da eseguire. */
	openJob(j: WfJob) {
		if (!j?.wfj_id) return;
		this.router.navigate(['execute', j.wfj_id], { relativeTo: this.route });
	}

	/** Tab 2: apre il dettaglio/timeline dell'istanza. */
	openInstance(i: WfInstance) {
		const id = this.instanceId(i);
		if (!id) return;
		this.router.navigate(['detail', id], { relativeTo: this.route, state: { title: this.instanceTitle(i) } });
	}
}
