import { HttpClient } from '@angular/common/http';
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { FormBuilder } from '@angular/forms';
import { Router } from '@angular/router';
import { Md5 } from 'ts-md5';
import { environment } from '../../environments/environment';
import { OrderService } from '../Services/order.service';
import { MatSnackBar } from '@angular/material/snack-bar';
import { UserService } from '../Services/userprofile.service';
import { CartItemViewModel, OrderViewModel } from '../shared/order';
import { PaymentViewModel } from '../shared/payment';
import { PaymentService } from '../Services/payment.service';
import { Subscription } from 'rxjs';

declare global {
  interface Window {
    payfast_do_onsite_payment: (param1: any, callback: any) => any;
  }
}

  @Component({
    selector: 'app-payfast',
    standalone: true,
    imports: [],
    templateUrl: './payfast.component.html',
    styleUrl: './payfast.component.css'
  })
  export class PayfastComponent implements OnInit {
    memberId!: number;
    finalAmount: number = 0;
    private finalAmountSubscription!: Subscription;

    constructor(private router : Router, private orderService : OrderService, private paymentService : PaymentService , private userService: UserService, private formBuilder: FormBuilder, private snackBar: MatSnackBar, private cdr: ChangeDetectorRef) {
      
    }

    ngOnInit(): void {
      this.fetchMemberId();
      this.finalAmountSubscription = this.paymentService.getFinalAmount().subscribe(amount => {
        this.finalAmount = amount;
        console.log("Retrieved final amount from subscription:", this.finalAmount); // Debugging line
        this.cdr.detectChanges(); // Force change detection
      });
    }

    ngOnDestroy(): void {
      if (this.finalAmountSubscription) {
        this.finalAmountSubscription.unsubscribe();
      }
    }

    getSignature(data : Map<string, string>) : string {
      let tmp = new URLSearchParams();
      data.forEach((v, k)=> {
        tmp.append(k, v)
      });
      let queryString = tmp.toString();
      let sig = Md5.hashStr(queryString);
      return sig;
    }

    async doOnSitePayment() {
      await this.fetchMemberId();

      let onSiteUserData = new Map<string, string>();
      onSiteUserData.set("merchant_id", "10033427")
      onSiteUserData.set("merchant_key", "mu83ipbgas9p7")

      onSiteUserData.set('return_url', window.location.origin + '/payment-success')
      onSiteUserData.set('cancel_url', window.location.origin + '/payment-cancel')

      // Gather required user data from orderService or other sources
      const userData = this.orderService.getUserData();
      onSiteUserData.set("email_address", userData.email);
      
      // Set amount and item_name
      onSiteUserData.set('amount', this.finalAmount.toFixed(2)); // Use the final amount from shared service
      onSiteUserData.set('item_name', 'Cart Purchase');

      // Optional passphrase for added security
      onSiteUserData.set('passphrase', 'HelloWorldHello'); // Use if you have a passphrase

      let signature = this.getSignature(onSiteUserData);
      onSiteUserData.set('signature', signature);

      let formData = new FormData();
      onSiteUserData.forEach((val, key) => {
        formData.append(key, val);
      });

      fetch(environment.payfastOnsiteEndpoint, {
        method: 'POST',
        body: formData,
        redirect: 'follow'
      })
      .then(response => response.json())
      .then(respJson => {
          let uuid = respJson['uuid'];
          window.payfast_do_onsite_payment({ 'uuid': uuid }, (res: any) => {
            if (res == true) {
              this.createOrder().then((orderResponse) => {
                this.createPayment(orderResponse);
                this.snackBar.open('Payment Successful', 'Close', { duration: 5000 });
              });         
            } else {
              this.snackBar.open('Payment Failed', 'Close', { duration: 5000 });              
            }
          });
        })
        .catch(error => {
          console.error('Error processing payment:', error);
          this.router.navigate(['/cancel']);
        });
      }

      //order
      private fetchMemberId() {
        const user = localStorage.getItem('User');
        if (user) {
          const userData = JSON.parse(user);
          this.memberId = userData.userId;
      
          // Optional: Fetch and validate member details if needed
          this.userService.getMemberByUserId(this.memberId).subscribe({
            next: (member) => {
              if (member && member.member_ID) {
                this.memberId = member.member_ID;
                console.log('Member ID:', this.memberId); // Check if this logs the correct ID
              } else {
                console.error('Member ID is undefined in the response');
                this.snackBar.open('Failed to retrieve member information', 'Close', { duration: 5000 });
              }
            },
            error: (error) => {
              console.error('Error fetching member:', error);
              this.snackBar.open('Failed to retrieve member information', 'Close', { duration: 5000 });
            }
          });
        } else {
          this.snackBar.open('User not logged in', 'Close', { duration: 5000 });
          this.router.navigate(['/login']);
        }
      }

      private createOrder(): Promise<OrderViewModel> {
        return new Promise((resolve, reject) => {
          if (this.memberId === undefined) {
            this.snackBar.open('Member ID is not available', 'Close', { duration: 5000 });
            reject('Member ID is not available');
          } else {
            this.orderService.getCartItems().subscribe({
              next: (cartItems) => {
                const order = this.prepareOrderDetails(cartItems);
                this.orderService.createOrder(order).subscribe({
                  next: (orderResponse) => {
                    this.snackBar.open('Order Created Successfully', 'Close', { duration: 5000 });
                    resolve(orderResponse);
                  },
                  error: (error) => {
                    console.error('Error creating order:', error);
                    this.snackBar.open('Failed to create order', 'Close', { duration: 5000 });
                    reject(error);
                  }
                });
              },
              error: (error) => {
                console.error('Error fetching cart items:', error);
                this.snackBar.open('Failed to fetch cart items', 'Close', { duration: 5000 });
                reject(error);
              }
            });
          }
        });
      }
      
    private prepareOrderDetails(cartItems: CartItemViewModel[]): OrderViewModel {
      const order: OrderViewModel = {
        order_ID: 0, // ID will be generated by backend
        member_ID: this.memberId,
        order_Date: new Date().toISOString(),
        total_Price: this.finalAmount, // Use the final amount from shared service
        order_Status_ID: 1, // Ready for Collection
        isCollected: false,
        orderLines: cartItems.map(item => ({
          order_Line_ID: 0, // ID will be generated by backend
          product_ID: item.product_ID,
          product_Name: item.product_Name,
          quantity: item.quantity,
          unit_Price: item.unit_Price
        }))
      };
    
      console.log('Prepared order details:', order);
      return order;
    }

    private createPayment(order: OrderViewModel) {
      const paymentData: PaymentViewModel = {
        payment_ID: 0,
        amount: order.total_Price, // Ensure this reflects VAT and discounts
        payment_Date: new Date().toISOString(),
        order_ID: order.order_ID,
        payment_Type_ID: 1 // Default to 1
      };

      this.paymentService.createPayment(paymentData).subscribe({
        next: (response) => {
          console.log('Payment record created successfully:', response);
          this.router.navigate(['/orders']);
        },
        error: (error) => {
          console.error('Error creating payment record:', error);
        }
      });
    }  
  }