import {
  phoneNumberOnly,
  toTime,
} from 'src/modules/queue/domain/helpers/time.helper';
import { WhatsappQueue } from './entity/whatsapp-queue.entity';
import {
  BOOKING_QR_URL,
  BOOKING_TICKET_URL,
  WHATSAPP_BUSINESS_ACCESS_TOKEN,
  WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID,
  WHATSAPP_BUSINESS_API_URL,
  WHATSAPP_BUSINESS_QUEUE_URL,
  WHATSAPP_BUSINESS_VERSION,
} from './whatsapp.constant';
import axios from 'axios';
import { Logger } from '@nestjs/common';
import { apm } from 'src/core/apm';
import { WhatsappBookingCreate } from './entity/booking.entity';
import * as moment from 'moment';

export class WhatsappService {
  async sendMessage(data) {
    const config = {
      method: 'post',
      url: `${WHATSAPP_BUSINESS_API_URL}/${WHATSAPP_BUSINESS_VERSION}/${WHATSAPP_BUSINESS_ACCOUNT_NUMBER_ID}/messages`,
      headers: {
        Authorization: `Bearer ${WHATSAPP_BUSINESS_ACCESS_TOKEN}`,
        'Content-Type': 'application/json',
      },
      data: data,
    };

    try {
      const response = await axios(config);
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error)) {
        if (error.response) {
          console.error('Axios error response:', {
            status: error.response.status,
            data: error.response.data,
            headers: error.response.headers,
            error: error.response.data?.error?.error_data,
          });
        } else if (error.request) {
          console.error('Axios error request:', error.request);
        } else {
          console.error('Axios error message:', error.message);
        }
      }
      Logger.error(error);
      apm?.captureError(error);
      return null;
    }
  }

  async queueRegister(data: WhatsappQueue) {
    const queueUrl = `${WHATSAPP_BUSINESS_QUEUE_URL}?id=${data.id}`;
    const payload = {
      messaging_product: 'whatsapp',
      to: phoneNumberOnly(data.phone), // recipient's phone number
      type: 'template',
      template: {
        name: 'queue_created',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'header',
            parameters: [
              {
                parameter_name: 'queue_code',
                type: 'text',
                text: data.code, // replace with queue_code variable
              },
            ],
          },
          {
            type: 'body',
            parameters: [
              {
                parameter_name: 'name',
                type: 'text',
                text: data.name, // replace with name variable
              },
              {
                parameter_name: 'item_name',
                type: 'text',
                text: data.item_name, // replace with item_name variable
              },
              {
                parameter_name: 'queue_code',
                type: 'text',
                text: data.code, // replace with queue_code variable
              },
              {
                parameter_name: 'queue_time',
                type: 'text',
                text: toTime(data.time), // replace with queue_time variable
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: '0',
            parameters: [
              {
                type: 'text',
                text: queueUrl, // replace with dynamic URL
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(
        `Notification register for ${data.code} send to ${data.phone}`,
      );
  }

  async bookingCreated(data: WhatsappBookingCreate) {
    const imageUrl = `${BOOKING_QR_URL}${data.id}`;

    const momentDate = moment(data.time);
    const fallbackValue = momentDate.locale('id').format('dddd, DD MMMM YYYY');
    // const dayOfWeek = momentDate.day();
    // const dayOfMonth = momentDate.date();
    // const year = momentDate.year();
    // const month = momentDate.month() + 1;
    // const hour = momentDate.hour();
    // const minute = momentDate.minute();

    const payload = {
      messaging_product: 'whatsapp',
      to: phoneNumberOnly(data.phone), // recipient's phone number
      type: 'template',
      template: {
        name: 'booking_online',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'header',
            parameters: [
              {
                type: 'image',
                image: {
                  link: imageUrl,
                },
              },
            ],
          },
          {
            type: 'body',
            parameters: [
              {
                type: 'text',
                parameter_name: 'customer',
                text: data.name, // replace with name variable
              },
              {
                type: 'text',
                parameter_name: 'booking_code',
                text: data.code, // replace with queue_code variable
              },
              {
                type: 'text',
                parameter_name: 'booking_date',
                text: fallbackValue,
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: '0',
            parameters: [
              {
                type: 'text',
                text: data.id, // replace with dynamic URL
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(
        `Notification register Booking for ${data.code} send to ${data.phone}`,
      );
  }

  async bookingExpired(data: WhatsappBookingCreate) {
    const momentDate = moment(data.time);
    const fallbackValue = momentDate.locale('id').format('dddd, DD MMMM YYYY');
    // const dayOfWeek = momentDate.day();
    // const dayOfMonth = momentDate.date();
    // const year = momentDate.year();
    // const month = momentDate.month() + 1;
    // const hour = momentDate.hour();
    // const minute = momentDate.minute();

    const payload = {
      messaging_product: 'whatsapp',
      to: phoneNumberOnly(data.phone), // recipient's phone number
      type: 'template',
      template: {
        name: 'booking_expired',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'body',
            parameters: [
              {
                type: 'text',
                parameter_name: 'customer',
                text: data.name, // replace with name variable
              },
              {
                type: 'text',
                parameter_name: 'code',
                text: data.code, // replace with queue_code variable
              },
              {
                type: 'text',
                parameter_name: 'booking_date',
                text: fallbackValue,
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(
        `Notification register Booking for ${data.code} send to ${data.phone}`,
      );
  }

  async rescheduleCreated(data: WhatsappBookingCreate) {
    const imageUrl = `${BOOKING_QR_URL}${data.id}`;

    const momentDate = moment(data.time);
    const fallbackValue = momentDate.locale('id').format('dddd, DD MMMM YYYY');
    // const dayOfWeek = momentDate.day();
    // const dayOfMonth = momentDate.date();
    // const year = momentDate.year();
    // const month = momentDate.month() + 1;
    // const hour = momentDate.hour();
    // const minute = momentDate.minute();

    const payload = {
      messaging_product: 'whatsapp',
      to: phoneNumberOnly(data.phone), // recipient's phone number
      type: 'template',
      template: {
        name: 'reschedule_created',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'header',
            parameters: [
              {
                type: 'image',
                image: {
                  link: imageUrl,
                },
              },
            ],
          },
          {
            type: 'body',
            parameters: [
              {
                type: 'text',
                parameter_name: 'customer',
                text: data.name, // replace with name variable
              },
              {
                type: 'text',
                parameter_name: 'booking_code',
                text: data.code, // replace with queue_code variable
              },
              {
                type: 'text',
                parameter_name: 'booking_date',
                text: fallbackValue,
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: '0',
            parameters: [
              {
                type: 'text',
                text: data.id, // replace with dynamic URL
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(
        `Notification register Booking for ${data.code} send to ${data.phone}`,
      );
  }

  async bookingRegister(
    data: WhatsappBookingCreate,
    total: number,
    paymentUrl: string,
  ) {
    const momentDate = moment(data.time);
    const fallbackValue = momentDate.locale('id').format('dddd, DD MMMM YYYY');

    const currentDate = moment().locale('id').format('DD MMMM YYYY');

    const formattedTotal = new Intl.NumberFormat('id-ID', {
      style: 'currency',
      currency: 'IDR',
      minimumFractionDigits: 0,
      maximumFractionDigits: 0,
    })
      .format(total)
      .replace('IDR', 'Rp');

    const payload = {
      messaging_product: 'whatsapp',
      to: phoneNumberOnly(data.phone), // recipient's phone number
      type: 'template',
      template: {
        name: 'booking_register',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'body',
            parameters: [
              {
                type: 'text',
                parameter_name: 'customer',
                text: data.name, // replace with name variable
              },
              {
                type: 'text',
                parameter_name: 'booking_date',
                text: fallbackValue,
              },
              {
                type: 'text',
                parameter_name: 'created_date',
                text: currentDate,
              },
              {
                type: 'text',
                parameter_name: 'booking_code',
                text: data.code,
              },
              {
                type: 'text',
                parameter_name: 'total',
                text: formattedTotal,
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: '0',
            parameters: [
              {
                type: 'text',
                text: paymentUrl, // replace with dynamic URL
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(
        `Notification register Booking for ${data.code} send to ${data.phone}`,
      );
  }

  async bookingRescheduleOTP(data: WhatsappBookingCreate) {
    const momentDate = moment(data.time);
    const fallbackValue = momentDate.locale('id').format('dddd, DD MMMM YYYY');

    const payload = {
      messaging_product: 'whatsapp',
      to: phoneNumberOnly(data.phone), // recipient's phone number
      type: 'template',
      template: {
        name: 'booking_reschedule',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'body',
            parameters: [
              {
                type: 'text',
                parameter_name: 'customer',
                text: data.name, // replace with name variable
              },
              {
                type: 'text',
                parameter_name: 'booking_code',
                text: data.code, // replace with queue_code variable
              },
              {
                type: 'text',
                parameter_name: 'booking_date',
                text: fallbackValue,
              },
              {
                type: 'text',
                parameter_name: 'otp',
                text: data.code,
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'copy_code',
            index: '0',
            parameters: [
              {
                type: 'coupon_code',
                coupon_code: data.code,
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(
        `Notification reschedule Booking for ${data.code} send to ${data.phone}`,
      );
  }

  async sendOtpNotification(data: { phone: string; code: string }) {
    // Compose the WhatsApp message payload for OTP using Facebook WhatsApp API
    const payload = {
      messaging_product: 'whatsapp',
      to: data.phone, // recipient's phone number in international format
      type: 'template',
      template: {
        name: 'booking_otp', // Make sure this template is approved in WhatsApp Business Manager
        language: {
          code: 'id', // or 'en' if you want English
        },
        components: [
          {
            type: 'body',
            parameters: [
              {
                type: 'text',
                text: parseInt(data.code), // OTP code
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: '0',
            parameters: [
              {
                type: 'text',
                text: `${data.code}`,
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response) {
      Logger.log(
        `OTP notification for code ${data.code} sent to ${data.phone}`,
      );
    }
  }

  async sendTemplateMessage(data: { phone: string; templateMsg: any }) {
    const payload = {
      messaging_product: 'whatsapp',
      to: data.phone,
      type: 'template',
      template: data?.templateMsg,
    };

    const response = await this.sendMessage(payload);
    if (response) {
      Logger.log(
        `OTP notification for template ${data.templateMsg} sent to ${data.phone}`,
      );
    }
  }

  async queueProcess(data: WhatsappQueue) {
    const queueUrl = `${WHATSAPP_BUSINESS_QUEUE_URL}?id=${data.id}`;
    const payload = {
      messaging_product: 'whatsapp',
      to: data.phone, // recipient's phone number
      type: 'template',
      template: {
        name: 'queue_process',
        language: {
          code: 'id', // language code
        },
        components: [
          {
            type: 'header',
            parameters: [
              {
                parameter_name: 'queue_code',
                type: 'text',
                text: data.item_name, // replace with queue_code variable
              },
            ],
          },
          {
            type: 'body',
            parameters: [
              {
                parameter_name: 'name',
                type: 'text',
                text: data.name, // replace with name variable
              },
              {
                parameter_name: 'queue_code',
                type: 'text',
                text: data.code, // replace with queue_code variable
              },
              {
                parameter_name: 'queue_time',
                type: 'text',
                text: toTime(data.time), // replace with queue_time variable
              },
            ],
          },
          {
            type: 'button',
            sub_type: 'url',
            index: '0',
            parameters: [
              {
                type: 'text',
                text: queueUrl, // replace with dynamic URL
              },
            ],
          },
        ],
      },
    };

    const response = await this.sendMessage(payload);
    if (response)
      Logger.log(`Notification process for ${data.code} send to ${data.phone}`);
  }
}
