// 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 { Router } from '@angular/router';
import { ModalController } from '@ionic/angular';
import { ActivatedRoute } from "@angular/router";
import { loadScript } from "@paypal/paypal-js";
import { Location } from '@angular/common';
import { Subscription } from 'rxjs';
import { TranslateService } from '@ngx-translate/core';

import { ConfigService } from 'src/app/providers/config.service';
import { ProdService } from 'src/app/providers/prod.service';
import { CartService } from 'src/app/providers/cart.service';
import { CustomerRegistrationService } from 'src/app/providers/customer-registration.service';
import { ModalAddressComponent } from 'src/app/components/modal-address/modal-address.component';
import { FatturaService } from 'src/app/providers/fattura.service';
import { DatiFiscali, RichiestaFatturaPayload, RigaFattura, datiFiscaliCompleti } from 'src/app/models/fattura.model';
import { ModalInvoiceRequestComponent } from 'src/app/components/modal-invoice-request/modal-invoice-request.component';

declare var PagaXpayJsFileFunction: any;

@Component({
  selector: 'app-cart',
  templateUrl: './cart.component.html',
  styleUrls: ['./cart.component.scss'],
  standalone: false,
})

export class CartComponent  implements OnInit {

  constructor(    
      private router: Router,
      private cartService: CartService,
      private activatedRoute: ActivatedRoute,
      private prodService: ProdService,
      private modalService: ModalController,
      private location: Location,
      private config: ConfigService,
      private translate: TranslateService,
      private configService: ConfigService,
      private customerRegistration: CustomerRegistrationService,
      private fatturaService: FatturaService,
  ){}

  // VARIABILI
  
	currentStep = 1;
  lst_operatordelivery: any[] = [];
  lst_typepayment: any[] = [];
  lst_typeproducts: any[] = [];
  lst_products: any[] = [];
  cur_address: any = {};
  delivery_address: any[] = [];
  buy: boolean = false;
  filter: any;
  filterTypewine:any;
  cmp_id!:number;
  prt_id!: number;
  lang!:string;
  upp!:boolean;
  cart: any;
  tpeopc: any;
  tpepay: any;
  payment: any={};
  cartDetail: any[] = [];
  // Richiesta fattura (checkout)
  requestInvoice = false;
  datiFiscali: DatiFiscali | null = null;
  onlineshopImageUrl = "";
  click_pay = false;
  responsiveOptions: any[] = [
    { breakpoint: '1024px', numVisible: 5 },
    { breakpoint: '768px', numVisible: 3 },
    { breakpoint: '560px', numVisible: 1 }
  ];

  // -----------------INIZIALIZZAZIONE PAGINA------------------------------------
  private paramsSubscription!: Subscription;
  ngOnInit(): void {
    this.onlineshopImageUrl = this.config.onlineshopImageUrl;
    this.paramsSubscription = this.activatedRoute.params.subscribe((params) => {
			if (params['cmp_id']) this.cmp_id = +params['cmp_id'];
      if (params['prt_id']) this.prt_id = +params['prt_id'];
		});
  }

  ionViewWillEnter() {
    this.lang = 'it';
    this.upp = true;
    this.resetFilter();
    this.resetFilterTypeWine();
    this.load_cart();
    this.prodService.get_typewine(this.filterTypewine).subscribe(res => {
      this.lst_typeproducts = res;
    });
    this.tpePay();
    this.opDel();
    this.load_get_address();
  }

  ngOnDestroy() {
		this.paramsSubscription?.unsubscribe();
	}

  // CARICAMENTO CARRELLO
  load_cart(){
    this.cartService.getCart(this.cmp_id, this.lang, this.upp).subscribe(res => {
      this.cart = res;
      this.cartDetail = res.detail;
    });
  }
  tpePay(){
    this.cartService.type_payment_get(this.cmp_id).subscribe(res => {
      this.lst_typepayment = res;
    });
  }
  opDel(){
    this.cartService.operator_delivery_get(this.cmp_id).subscribe(res => {
      this.lst_operatordelivery = res;
    });
  }
  
  load_get_address(){
    this.cur_address = {};
    this.delivery_address = [];
    let objSearchDB: any = {};
    objSearchDB.orderBy = '';
    objSearchDB.pagina = 1;
    objSearchDB.righePagina = 1000;
    this.cartService.delivery_address_get(this.cmp_id, objSearchDB).subscribe(res => {
      this.delivery_address = res;

      if (res[0]) {
        this.delivery_address.forEach(element => {
          if (element.isactive) {
            this.cur_address = element;
          }
        });
        if (!this.cur_address?.id) {
          this.cur_address = this.delivery_address[0];
        }
      }
    });
  }

  // RESET FILTERS

  resetFilter() {
    this.filter = {};
    this.filter.cmp_id = this.cmp_id;
    this.filter.pagina = 1;
    this.filter.righePagina = 10;
    this.filter.orderBy = 'prd_title';
    this.filter.type_wine = -1;
    this.filter.price_from = null;
    this.filter.price_to = null;
  }

  resetFilterTypeWine(){
    this.filterTypewine = {};
    this.filterTypewine.tpw_cmp_id = this.cmp_id;
    this.filterTypewine.pagina = 1;
    this.filterTypewine.righePagina = 99999;
    this.filterTypewine.orderBy = 'tpw_name';
  }

  // AZIONI DEL CARRELLO

  PrdPurchase(){
     this.buy = true;
     this.tpePay();
     this.opDel();
     this.load_get_address();
  }

  changeQuantity(prd : any, type : string){
    prd.cmp_id = this.cmp_id;
    prd.title.trim();
    switch(type){

      case 'minus':
        prd.qnt--;
        this.cartService.addPrdCart(prd).subscribe(res => 
          {this.load_cart();}
        );
      break;
      case 'plus':
        prd.qnt++;
        this.cartService.addPrdCart(prd).subscribe(res => 
          {this.load_cart();}
        );
      break;
      case 'remove':
        prd.qnt = 0;
        this.cartService.addPrdCart(prd).subscribe(res => 
          {this.load_cart();}
        );
        break;
      default:
        break;

    }
  }

  // --------------MODAL ADDRESS---------------------------
  newAddress(){
    let id = 0;
    this.ModalAddress(id);
  }

  updAddress(address: any){
    this.ModalAddress(address.uda_id);
  }

  delAddress(address: any){
    this.cartService.delivery_address_del(address.uda_id).subscribe(() =>{
      this.PrdPurchase();
    });
  }

  async ModalAddress(id_add: number){
      const modal =  await this.modalService.create({
        component:ModalAddressComponent,
         componentProps: {
          id: id_add,
          cmp_id: this.cmp_id,
         }
      });
      modal.onDidDismiss().then(() => {this.PrdPurchase();});

    return await modal.present();
  }


  //----------------------------------------------------------------
  //-----------------------PAGAMENTO--------------------------------
  //----------------------------------------------------------------

  /** true quando il metodo selezionato è PayPal (id=1) */
  get isPaypal(): boolean { return this.tpepay?.tpepay_id === 1; }

  /** Popola l'oggetto payment con le scelte fatte negli step precedenti */
  private preparePayment() {
    this.payment.cart = this.cart;
    this.payment.operator_delivery_id = this.tpeopc?.opc_id;
    this.payment.type_payment_id = this.tpepay?.tpepay_id;
    this.payment.delivery_address = this.cur_address;
  }

  pay(){
    this.preparePayment();
    switch (this.tpepay?.tpepay_id) {
      case 4: // CONTANTI
        this.click_pay = true;
        this.SavePayment();
        break;
      case 2: // Nexi
        this.click_pay = true;
        this.CallPagaXpayJsFileFunction();
        break;
      // PayPal (id=1): gestito dai bottoni nativi PayPal renderizzati nel container
    }
  }

  CallPagaXpayJsFileFunction() {

    this.cartService.getConfigPayment(this.cmp_id, this.payment).subscribe(data => {
      console.log('getConfigPayment - Nexi', data);

      PagaXpayJsFileFunction(data);

      window.addEventListener('XPay_Payment_Result', (event: any) => {
        console.log('XPay_Payment_Result', event.detail);

        switch (event.detail.esito) {
          case 'ANNULLO':
            this.translate.get('carrello.pagamento_ann').subscribe(res => {
              this.configService.presentToastError(res);
            });
            this.click_pay = false;
            break;
          case 'OK':
            this.payment.responsePaymentDetail = JSON.stringify(event.detail);
            this.payment.idTransaction = event.detail.codTrans;
            this.SavePayment();
            break;
          default:
            this.translate.get('carrello.pagamento_ko').subscribe(res => {
              this.configService.presentToastError(res +  '. [' + event.detail.codiceEsito + '] ' + event.detail.messaggio);
            });
            this.click_pay = false;
            break;
        }
      }, { once: true });
    });
  }

  SavePayment() {
    this.cartService.savePayment(this.cmp_id, this.payment).subscribe((data: any) => {
      // Registra l'utente come cliente dell'azienda (+ dipendente) se non lo è già.
      // Non bloccante: non deve compromettere l'esito dell'ordine.
      this.customerRegistration.ensureCustomerForCurrentUser(this.cmp_id).subscribe();
      // Pagamento confermato -> se richiesta, crea la fattura (invio a SDI via scheduler).
      const ordId = typeof data === 'number' ? data : Number(data?.ord_id ?? data?.body ?? 0);
      this._creaFatturaSeRichiesta(ordId);
      this.translate.get('carrello.pagamento_ok').subscribe(res => {
        this.configService.presentToastSuccess(res);
      });
      this.cartService.set_num_product(null);
      this.router.navigate(['']);
    });
  }

  // ── Richiesta fattura ────────────────────────────────────────────

  /** Toggle "Richiedi fattura": raccoglie i dati fiscali (modale) se il cliente non è completo. */
  onToggleRichiediFattura() {
    if (!this.requestInvoice) { this.datiFiscali = null; return; }
    this.fatturaService.getMyFiscalData(this.cmp_id).subscribe(async (d) => {
      if (d && datiFiscaliCompleti(d)) { this.datiFiscali = d; return; }
      const modal = await this.modalService.create({
        component: ModalInvoiceRequestComponent,
        componentProps: { cmp_id: this.cmp_id, prefill: d },
      });
      await modal.present();
      const { data, role } = await modal.onDidDismiss();
      if (role === 'confirm' && data) this.datiFiscali = data as DatiFiscali;
      else this.requestInvoice = false;
    });
  }

  /** Riapre la modale dati fiscali precompilata per correggerli prima del pagamento. */
  async modificaDatiFiscali() {
    const modal = await this.modalService.create({
      component: ModalInvoiceRequestComponent,
      componentProps: { cmp_id: this.cmp_id, prefill: this.datiFiscali },
    });
    await modal.present();
    const { data, role } = await modal.onDidDismiss();
    if (role === 'confirm' && data) this.datiFiscali = data as DatiFiscali;
  }

  /** A pagamento confermato: crea la richiesta di fattura per l'ordine. */
  private _creaFatturaSeRichiesta(ordId: number) {
    if (!this.requestInvoice || !this.datiFiscali || !(ordId > 0)) return;
    // Una riga per PRODOTTO dell'ordine (dal dettaglio carrello), non una riga unica.
    let righe: RigaFattura[] = (this.cartDetail || []).map((d: any) => {
      const p = d.product || d;
      const aliquota = Number(p.vatRate ?? p.prd_vat_rate ?? 22) || 22;
      const qta = Number(p.qnt ?? p.amount ?? 1) || 1;
      const lordoUnit = Number(p.price) || 0;
      return {
        descrizione: p.title || 'Prodotto',
        quantita: qta,
        prezzoUnitario: this._nettoDaLordo(lordoUnit, aliquota),
        aliquotaIVA: aliquota,
      } as RigaFattura;
    });
    // Fallback: se il dettaglio non è disponibile, una riga sul totale
    if (righe.length === 0) {
      const gross = Number(this.cart?.price_payment) || 0;
      righe = [{ descrizione: 'Ordine online', quantita: 1, prezzoUnitario: this._nettoDaLordo(gross, 22), aliquotaIVA: 22 }];
    }
    const oggi = new Date().toISOString().substring(0, 10);
    const payload: RichiestaFatturaPayload = {
      cmp_id: this.cmp_id,
      module: 'ECOMMERCE',
      entity_id: ordId,
      datiFiscali: this.datiFiscali,
      righe,
      pagamento: { metodoSdi: this._mpDaTpePay(this.tpepay?.tpepay_id), pagata: true, dataPagamento: oggi },
    };
    this.fatturaService.requestInvoice(payload).subscribe({
      next: () => this.configService.presentToastSuccess('Fattura richiesta: sarà inviata a breve'),
      error: () => this.configService.presentToastError('Errore nella richiesta fattura'),
    });
  }

  private _nettoDaLordo(lordo: number, aliquota: number): number {
    const netto = lordo / (1 + aliquota / 100);
    return Math.round(netto * 100) / 100;
  }

  /** Codice ModalitaPagamento SDI da tpepay_id (1=PayPal, 2=Nexi, 4=Contanti). */
  private _mpDaTpePay(tpepayId: number): string {
    switch (Number(tpepayId)) {
      case 1: return 'MP08'; // PayPal
      case 2: return 'MP08'; // Nexi (carta)
      case 4: return 'MP01'; // Contanti
      default: return 'MP05';
    }
  }

  PayPalPayment() {
      this.cartService.getConfigPayment(this.cmp_id, this.payment).subscribe(config => {
        console.log('getConfigPayment - PayPal', config);

        let paypal_container = document.getElementById('paypal-button-container');
        if (paypal_container) {
          paypal_container.innerHTML = ''
        }

        loadScript({ clientId: this.config.paypal_clientId, currency: "EUR" })
          .then((paypal: any) => {
            paypal
              .Buttons({
                style: {
                  layout: 'horizontal',
                  shape: 'rect',
                  tagline: false
                },

                createOrder: (data: any, actions: any) => {
                  if (!this.cur_address?.id) {
                    return actions.order.create({
                      intent: config.intent,
                      purchase_units: [{
                        reference_id: config.purchase_unit[0].reference_id,
                        custom_id: config.purchase_unit[0].custom_id,
                        amount: {
                          value: config.purchase_unit[0].amount.value,
                          currency_code: config.purchase_unit[0].amount.currency_code,
                        }
                      }]
                    });
                  } else {
                    return actions.order.create({
                      intent: config.intent,
                      purchase_units: [{
                        reference_id: config.purchase_unit[0].reference_id,
                        custom_id: config.purchase_unit[0].custom_id,
                        amount: {
                          value: config.purchase_unit[0].amount.value,
                          currency_code: config.purchase_unit[0].amount.currency_code,
                        },
                        shipping: {
                          type: config.purchase_unit[0].shipping.type,
                          address: {
                            address_line_1: config.purchase_unit[0].shipping.address.address_line_1,
                            address_line_2: config.purchase_unit[0].shipping.address.address_line_2,
                            admin_area_2: config.purchase_unit[0].shipping.address.admin_area_2,
                            admin_area_1: config.purchase_unit[0].shipping.address.admin_area_1,
                            postal_code: config.purchase_unit[0].shipping.address.postal_code,
                            country_code: config.purchase_unit[0].shipping.address.country_code
                          }
                        }
                      }]
                    });
                  }
                },

                onApprove: (data: any, actions: any) => {
                  return actions.order.capture()
                    .then((details: any) => {
                      console.log('onApprove', details);

                      this.payment.responsePaymentDetail = JSON.stringify(details);
                      this.payment.idTransaction = details.purchase_units[0].reference_id;
                      this.SavePayment();
                    });
                },

                onShippingChange: function () {
                  return (data: any, actions: any) => {
                    console.log('onShippingChange', data);
                  }
                },

                onCancel: (data: any, actions: any) => {
                  console.log('onCancel', data);

                this.translate.get('carrello.pagamento_ann').subscribe(res => {
                  this.configService.presentToastError(res);
                  });
                },

                onError: (err: any) => {
                  console.log('onError', err);

                this.translate.get('carrello.pagamento_ann').subscribe(res => {
                  this.configService.presentToastError(res);
                  });
                }

              })
              .render("#paypal-button-container")
              .catch((error: any) => {
                console.error("failed to render the PayPal Buttons", error);
              });
          })
          .catch((error: any) => {
            console.error("failed to load the PayPal JS SDK script", error);
          });
      });
    }
  

  // INIDIRIZZAMENTI

  prd_detail(prd_id: number){
    this.router.navigate(['/portale', this.prt_id, 'company', this.cmp_id, 'service', 'onlineshop', 'product-detail', prd_id ]);
  }
  
  goToPrd(){
    this.router.navigate(['/portale', this.prt_id, 'company', this.cmp_id, 'service', 'onlineshop', 'products']);
  }

  acquista(){
    this.buy = true;
  }

  // Logo del corriere ricavato automaticamente dal nome (opc_desc):
  // nome -> dominio ufficiale -> logo via servizio favicon pubblico Google.
  // Se il corriere non è riconosciuto o il logo non carica, la card mostra
  // l'icona cubo di fallback (vedi template, op._logoError).
  courierLogo(op: any): string {
    const domain = this._courierDomain(op?.opc_desc);
    return domain ? `https://www.google.com/s2/favicons?domain=${domain}&sz=128` : '';
  }

  private _courierDomain(desc: string): string {
    const d = (desc || '').toLowerCase();
    const map: { [k: string]: string } = {
      brt: 'brt.it',
      dhl: 'dhl.com',
      fedex: 'fedex.com',
      gls: 'gls-group.com',
      ups: 'ups.com',
      tnt: 'tnt.com',
      sda: 'sda.it',
      nexive: 'nexive.it',
      inpost: 'inpost.it',
      amazon: 'amazon.com',
      poste: 'poste.it',
    };
    const key = Object.keys(map).find(k => d.includes(k));
    return key ? map[key] : '';
  }

  // Icona del metodo di pagamento (allineata alle card di Prenotazioni)
  paymentIcon(pt: any): string {
    switch (pt?.tpepay_id) {
      case 1:  return 'logo-paypal';   // PayPal
      case 2:  return 'card-outline';  // Nexi
      case 4:  return 'cash-outline';  // Contanti
      default: return 'wallet-outline';
    }
  }

  goToStep(step: number) { this.currentStep = step; }
  nextStep() {
    this.currentStep++;
    // Arrivati al riepilogo con PayPal: renderizza i bottoni nativi PayPal
    if (this.currentStep === 3 && this.isPaypal) {
      this.preparePayment();
      setTimeout(() => this.PayPalPayment(), 150);
    }
  }
	prevStep()  { if (this.currentStep > 1) this.currentStep--; }

  goBack(): void{
    this.location.back();
  }


}
