// 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 { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, of } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';

import { ConfigService } from './config.service';
import { SopralluogoCmp, SopralluogoTipo } from '../models/sopralluogo-cmp.model';

// Radice documentale ("Document Management"): sotto vive la cartella di ogni condominio (come il web)
const ROOT_DOCUMENT_MANAGEMENT = 2;

/**
 * Sopralluoghi — NUOVA gestione ws_spring_cmp (endpoint /sopralluoghi/*), come il web.
 * Distinto dal vecchio RFI (providers/sopralluoghi.service.ts).
 */
@Injectable({ providedIn: 'root' })
export class SopralluoghiCmpService {
	constructor(
		private http: HttpClient,
		private config: ConfigService,
	) {}

	private get base(): string {
		return this.config.serviceUrl_Companies;
	}

	getSopralluoghi(cmp_id: number, ws_id = 0, origin = '', data_da = '', data_a = '', txtsearch = '', order_by = 'sl_data_apertura_sopralluogo DESC', limit = 100, offset = 1): Observable<SopralluogoCmp[]> {
		const url =
			`${this.base}sopralluoghi/list?cmp_id=${cmp_id}&ws_id=${ws_id}&origin=${encodeURIComponent(origin)}` +
			`&data_da=${encodeURIComponent(data_da)}&data_a=${encodeURIComponent(data_a)}&txtsearch=${encodeURIComponent(txtsearch)}` +
			`&order_by=${encodeURIComponent(order_by)}&limit=${limit}&offset=${offset}`;
		return this.http.get<SopralluogoCmp[]>(url, { observe: 'response' }).pipe(map((r) => r.body || []));
	}

	getSopralluogo(sl_id: number): Observable<SopralluogoCmp> {
		return this.http.get<SopralluogoCmp>(`${this.base}sopralluoghi/get?sl_id=${sl_id}`, { observe: 'response' }).pipe(map((r) => r.body as SopralluogoCmp));
	}

	addUpdSopralluogo(s: SopralluogoCmp): Observable<number> {
		const url = s.sl_id > 0 ? `${this.base}sopralluoghi/upd` : `${this.base}sopralluoghi/add`;
		return this.http.post<number>(url, s, { observe: 'response' }).pipe(map((r) => Number(r.body) || 0));
	}

	delSopralluogo(sl_id: number): Observable<any> {
		return this.http.delete(`${this.base}sopralluoghi/del/${sl_id}`, { observe: 'response' }).pipe(map((r) => r.body));
	}

	getTipi(): Observable<SopralluogoTipo[]> {
		return this.http.get<SopralluogoTipo[]>(`${this.base}sopralluoghi/tipi`, { observe: 'response' }).pipe(map((r) => r.body || []));
	}

	// --- flusso stati ---
	convalida(sl_id: number, costo_effettivo?: number | null): Observable<any> {
		const q = costo_effettivo != null ? `&costo_effettivo=${costo_effettivo}` : '';
		return this.http.post(`${this.base}sopralluoghi/convalida?sl_id=${sl_id}${q}`, null, { observe: 'response' }).pipe(map((r) => r.body));
	}
	contabilizza(sl_id: number): Observable<any> {
		return this.http.post(`${this.base}sopralluoghi/contabilizza?sl_id=${sl_id}`, null, { observe: 'response' }).pipe(map((r) => r.body));
	}
	fattura(sl_id: number): Observable<any> {
		return this.http.post(`${this.base}sopralluoghi/fattura?sl_id=${sl_id}`, null, { observe: 'response' }).pipe(map((r) => r.body));
	}
	annulla(sl_id: number): Observable<any> {
		return this.http.post(`${this.base}sopralluoghi/annulla?sl_id=${sl_id}`, null, { observe: 'response' }).pipe(map((r) => r.body));
	}
	resetStato(sl_id: number): Observable<any> {
		return this.http.post(`${this.base}sopralluoghi/reset_stato?sl_id=${sl_id}`, null, { observe: 'response' }).pipe(map((r) => r.body));
	}

	// --- cartella documentale + allegati (documentale, come il web) ---
	setFolder(sl_id: number, folder_id: number): Observable<any> {
		return this.http.post(`${this.base}sopralluoghi/setfolder?sl_id=${sl_id}&folder_id=${folder_id}`, null, { observe: 'response' }).pipe(map((r) => r.body));
	}

	/** Garantisce e collega la cartella: ROOT / <Condominio> / Sopralluoghi / <id - protocollo>. */
	ensureFolder(cmp_id: number, sl_id: number, protocollo: string): Observable<number> {
		return this.http.get<any>(`${this.base}companies/get?cmp_id=${cmp_id}`, { observe: 'response' }).pipe(
			map((r) => (r.body?.name as string) || ''),
			switchMap((companyName: string) => {
				const names = [companyName, 'Sopralluoghi', sl_id + ' - ' + (protocollo || '')];
				const leaf$ = names.reduce(
					(acc$: Observable<number>, name: string) => acc$.pipe(switchMap((parentId: number) => this.getOrCreateFolder(name, parentId, cmp_id))),
					of(ROOT_DOCUMENT_MANAGEMENT) as Observable<number>,
				);
				return leaf$.pipe(switchMap((leafId: number) => this.setFolder(sl_id, leafId).pipe(map(() => leafId))));
			}),
		);
	}

	private getOrCreateFolder(name: string, idParent: number, cmp_id: number): Observable<number> {
		const folder = { view_name: name, id_parent: idParent, drfrm_id: 0 };
		return this.http
			.post<any>(`${this.config.serviceUrl_Documentary}folder/verifyFolderExists/${cmp_id}`, folder, { observe: 'response' })
			.pipe(map((r) => (typeof r.body === 'number' ? r.body : r.body?.id || 0)));
	}

	listDocumenti(folderId: number, cmp_id: number): Observable<any[]> {
		const filter = { id_folder: folderId, cmp_id: cmp_id, pagina: 1, righePagina: 1000, orderBy: 'drfl_id desc', stato: '-1', search_sottocartelle: false, campi_form: '' };
		return this.http.post<any>(`${this.config.serviceUrl_Documentary}file/get_lista_file`, filter, { observe: 'response' }).pipe(map((r) => (Array.isArray(r.body) ? r.body : r.body?.files || [])));
	}

	/** Upload allegato (PDF) nella cartella del sopralluogo — 2 step come il web. */
	uploadDocumento(folderId: number, file: File): Observable<number> {
		const fd1 = new FormData();
		fd1.append('fileUpload[]', file);
		return this.http.post<{ res: string }>(`${this.config.serviceUrl_Documentary}file/insert_pdf_file_in_folder_temp`, fd1, { observe: 'response' }).pipe(
			map((r) => r.body?.res || ''),
			switchMap((tempPath) => {
				if (!tempPath) return of(0);
				const fd2 = new FormData();
				fd2.append('metadata_file', '{}');
				fd2.append('file_path', tempPath);
				fd2.append('original_file_name', file.name);
				fd2.append('drfl_description', '');
				return this.http.post<number>(`${this.config.serviceUrl_Documentary}file/insert_new_file/${folderId}`, fd2, { observe: 'response' }).pipe(map((r) => Number(r.body) || 0));
			}),
		);
	}

	/** Scarica un file documentale (file_dwn_zip → temp → url). */
	fileDownloadUrl(drfl_id: number): Observable<string> {
		const payload = { lst_folder: [], lst_file: [{ id: drfl_id, type: 'D' }] };
		return this.http.post<{ res: string }>(`${this.config.serviceUrl_Documentary}file/file_dwn_zip`, payload, { observe: 'response' }).pipe(map((r) => (r.body?.res ? this.config.imageBaseURL + '/temp/' + r.body.res : '')));
	}
}
