;(function($, undefined) {
  const {ssa, user_id, included_products, past_appointments, translations} = ssaMeprAccountView;

  const $iframesContainer        = $('#ssa-mepr-booking-app-container');
  const $iframes                 = $('.ssa-mepr-booking-app-iframe-container');
  const $appointmentTableBody    = $('#ssa-mepr-appointments-table-body');
  const $appointmentsTable       = $('#mepr-account-appointment-table');
  const $pastAppointmentsSection = $('#ssa-mepr__past-appointments-section');
  const $backBtn                 = $('#ssa-mepr-back-appointments')

  // Add eventListener on Book Now buttons
  $appointmentTableBody.on('click', '.ssa-mepr-book-now', function($event, el) {
    $event.preventDefault();
    bookNow(this);
  });

  $backBtn.on('click', function() {
    $iframes.fadeOut(300);
    $iframesContainer.fadeOut(300, function(){
      $appointmentsTable.show()
      $pastAppointmentsSection.show();
    });
    render();
  })

  function bookNow(el) {
    var appointment_type_id = $(el).data('appointment_type_id');
    var membership_id = $(el).data('membership_id');
    let $iframe = $(`.ssa-mepr-booking-app-iframe-container[data-type-id="${appointment_type_id}"][data-product-id="${membership_id}"]`);

    $pastAppointmentsSection.fadeOut(300);
    $appointmentsTable.fadeOut(300, function(){
      $iframesContainer.fadeIn();
      $iframe.show();
      $('html, body').animate({
        scrollTop: $iframe.offset().top
      }, 500);
    });
  }

  function fetchCurrentCycleAppointmentsPerProduct(appointment_type_id, product_id ) {
    return new Promise((resolve, reject) => {
      $.ajax({
        url: ssa.api.root + '/memberpress/user/curr_cycle_appointments_per_product',
        method: 'GET',
        data: {
          user_id,
          appointment_type_id,
          product_id
        },
        cache: false,
        dataType: 'json',
        contentType: 'application/json',
        beforeSend: (xhr) => {
          xhr.setRequestHeader('X-WP-Nonce', ssa.api.nonce)
        }
      })
        .done((data) => {
          resolve(data.data)
        })
        .fail((xhr, status, error) => {
          reject(error)
        })
    })
  }

  function renderUpcomingAppointments(){
    var $tbody = $('#ssa-mepr-appointments-table-body');
    $tbody.empty()

    // Create an array to store all the promises
    var promises = [];
    var rows = [];

    $.each(included_products, function(index, product) {
      $.each(product.appointment_types, function(appointment_type_id, appointment_type) {
        let allowTrialBooking = appointment_type.allow_booking_during_trials
        let is_on_trial = product.is_on_trial

        if (!allowTrialBooking && is_on_trial) {
          return; // Skip this iteration
        }

        let product_id = product.product_id
        let limit_booking_per_cycle = appointment_type.limit_booking_per_cycle;
        let max_num_of_appointments_per_cycle = appointment_type.max_num_of_appointments_per_cycle;
        let is_renewable = product.is_renewable
        let is_active = appointment_type.active
        let active_txn_count = product.active_txn_count || 1; // Number of active transactions/renewals

        var tr = $('<tr>').addClass('mepr-appointment-row');
        let membershipCell = $('<td>').addClass('ssa-loading-indicator').text(product.membership).appendTo(tr);
        let appointmentTypesCell = $('<td>').addClass('ssa-loading-indicator').text(translations.loading + '...').appendTo(tr);
        let bookedCell = $('<td>').addClass('ssa-loading-indicator').text(translations.loading + '...').appendTo(tr)
        $tbody.append(tr);

        promises.push(fetchCurrentCycleAppointmentsPerProduct(appointment_type_id, product.product_id));
        rows.push({
          // Info
          appointment_type,
          limit_booking_per_cycle,
          max_num_of_appointments_per_cycle,
          appointment_type_id,
          is_renewable,
          is_on_trial,
          product_id,
          is_active,
          active_txn_count,
          // Row & Cells
          tr,
          membershipCell,
          appointmentTypesCell,
          bookedCell,
        });
      });
    });

    // Wait for all the promises to resolve
    Promise.all(promises)
      .then(function(dataArray) {
        // Loop through the data and update the corresponding cells
        dataArray.forEach(function(appointments, i) {
          let row = rows[i];

          // If appointment type is inactive and there are no upcoming appointments, remove the row
          if (!row.is_active && getUpcoming(appointments).length == 0) {
            row.tr.remove();
            return;
          }

          row.membershipCell.removeClass('ssa-loading-indicator');
          row.appointmentTypesCell.removeClass('ssa-loading-indicator').html(parseApptTypeInfo(row));
          row.bookedCell.removeClass('ssa-loading-indicator').html(parseAppointmentsDate(appointments, row));
        });

        // Check if the tbody is empty
        if ($tbody.children().length === 0) {
          var $tr = $('<tr>');
          $('<td>').attr('colspan', '3')
                   .css({'text-align': 'center', 'padding': '20px'})
                   .text(translations.empty_table_msg)
                   .appendTo($tr);
          $tbody.append($tr);
        }

      })
  }

  function getUpcoming(appointments){
    let currentDate = new Date();

    let upcomingAppointments = appointments.filter(function(appointment){
        let appointmentEndDate = new Date(appointment.end_date + "Z");

        // Return true if the appointment's end date is in the future, false otherwise
        return appointmentEndDate > currentDate;
    });

    return upcomingAppointments;
  }

  function parseAppointmentsDate(appointments, info){
    let $output = $('<div>').addClass('ssa-mepr_cell__upcoming-appts')

    let upcomingAppts = getUpcoming(appointments);
    // If no upcoming appointments
    if(upcomingAppts.length === 0){
      $('<span>').text(translations.none).appendTo($output);

    } else {
      let $ul = $('<ul>');
      $.each(upcomingAppts, function(key, value){

        let $date = $('<span>').text(value.formatted_start_date);
  
        let $link = $('<a>', {
          target: '_blank',
          href: value.public_edit_url,
          text: translations.view_details,
          class: 'ssa-mepr_cell__upcoming-appts_link'
        });
  
        $('<li>').append(
          $date,
          $link
        ).appendTo($ul)
      })
      $ul.appendTo($output)
    }

    // Book now btn & remaining
    if(info.is_active){
      let $cellFooter = parseRemaining(appointments, info);
      $cellFooter.appendTo($output);
    }


    return $output;
  }

  function parseRemaining(appointments, info){
    let canBook = true;
    let $output = $('<div>');
    let count   = appointments.length;
    let remaining;
    let totalAllowed; // Total allowed appointments considering early renewals

    if (info.is_on_trial){
      remaining = info.appointment_type.max_num_of_appointments_during_trials - count;
      if (remaining <= 0){
        $('<span>').addClass('ssa-mepr_grayed-out').text(translations.no_remaining_appointments).appendTo($output);
        canBook = false;
      }
      else if (remaining === 1) {
        $('<span>').addClass('ssa-mepr_grayed-out').text(translations.x_remaining_appointment).appendTo($output);
      }
      else {
        let remainingText = translations.x_remaining_appointments.replace('%d', remaining)
        $('<span>').addClass('ssa-mepr_grayed-out').text(remainingText).appendTo($output);
      }
    } 

    // Check for booking limit per cycle
    else if (info.limit_booking_per_cycle && !info.is_renewable){
      // For non-renewable memberships with early renewals, multiply limit by number of active transactions
      totalAllowed = info.max_num_of_appointments_per_cycle * (info.active_txn_count || 1);
      remaining = totalAllowed - count;
      
      if(remaining <= 0){
        $('<span>').addClass('ssa-mepr_grayed-out').text(translations.no_remaining_appointments).appendTo($output);
        canBook = false;
      } 
      else if (remaining === 1) {
        $('<span>').addClass('ssa-mepr_grayed-out').text(translations.x_remaining_appointment).appendTo($output);
      }
      else {
        let remainingText = translations.x_remaining_appointments.replace('%d', remaining)
        $('<span>').addClass('ssa-mepr_grayed-out').text(remainingText).appendTo($output);
      }
    }

    if(canBook) {
      $('<br>').prependTo($output)

      $('<button>')
        .data('appointment_type_id', info.appointment_type_id)
        .data('membership_id', info.product_id)
        .addClass(['ssa-btn-raised', 'ssa-mepr-book-now'])
        .text(translations.book_now)
        .prependTo($output)
    }
      
    return $output;
  }

  function parseApptTypeInfo(info){

    let appointment_type = info.appointment_type;

    let rowContent = $('<div>').addClass('ssa-mepr_cell__appttype');
    $('<span>').addClass('ssa-mepr_cell__appttype-title').text(appointment_type.title).appendTo(rowContent);
    $('<br>').appendTo(rowContent);

    // If the appointment type is longer active display a message instead of its settings
    if (!info.is_active) {
      $('<span>').addClass(['ssa-mepr_grayed-out','ssa-mepr_cell__appttype-info']).text(translations.typeNoLongerActive).appendTo(rowContent);
      $('<br>').appendTo(rowContent);
      $('<span>').addClass(['ssa-mepr_grayed-out','ssa-mepr_cell__appttype-info']).text(translations.accessExistingAppts).appendTo(rowContent);
    
    } else {
      $('<span>').addClass(['ssa-mepr_grayed-out','ssa-mepr_cell__appttype-info']).text(localizePerIntervalStr(appointment_type)).appendTo(rowContent);
      if (appointment_type.limit_booking_per_cycle) {
        $('<br>').appendTo(rowContent);
        $('<span>').addClass(['ssa-mepr_grayed-out','ssa-mepr_cell__appttype-info']).text(localizePerCycleStr(appointment_type)).appendTo(rowContent);
      }
    }
    // If on trial period
    if (info.is_on_trial) {
      $('<br>').appendTo(rowContent);
      $('<span>').addClass(['ssa-mepr_grayed-out','ssa-mepr_cell__appttype-info']).text(localizeTrialPeriodStr(appointment_type)).appendTo(rowContent);
    }

    return rowContent;
  }

  function localizePerIntervalStr(appointment_type){
    let per_interval = parseInt(appointment_type.per_interval);
    let interval_type = appointment_type.interval_type
    // singular - singular
    if(per_interval === 1) {
      return translations.singular_appointment_per_singular_interval.replace('%s', translations[interval_type]);
    } 
    // plural - singular
    else if (per_interval > 1){
      return translations.plural_appointment_per_singular_interval.replace('%d', per_interval).replace('%s', translations[interval_type]);
    }
  }

  function localizeTrialPeriodStr(appointment_type){
    let per_trial = parseInt(appointment_type.max_num_of_appointments_during_trials);
    if(per_trial === 1) {
      return translations.singular_appointment_during_trial;
    } 
    else if (per_trial > 1){
      return translations.plural_appointments_during_trial.replace('%d', per_trial);
    }
  }

  function localizePerCycleStr(appointment_type){
    let per_cycle = parseInt(appointment_type.max_num_of_appointments_per_cycle);
    // singular
    if(per_cycle === 1) {
      return translations.appointment_per_cycle
    }
    // plural
    else {
      return translations.appointments_per_cycle.replace('%d', per_cycle)
    }
  }

  /* ------- Past appointments section ------- */

  const $membershipIdFilter      = $('#ssa_mepr_select_membership');
  const $appointmentTypeIdFilter = $('#ssa_mepr_select_appointment_types');
  const $dateFilterFilter        = $('#ssa_mepr_select_date');
  const $statusFilter            = $('#ssa_mepr_select_status'); 

  const filters = [
    $membershipIdFilter, 
    $appointmentTypeIdFilter, 
    $dateFilterFilter, 
    $statusFilter
  ];

  filters.forEach($filter => {
    $filter.change(renderPastAppointments);
  });

  function renderPastAppointments() {
    const membershipId      = $membershipIdFilter.val();
    const appointmentTypeId = $appointmentTypeIdFilter.val();
    const dateFilter        = $dateFilterFilter.val();
    const statusFilter      = $statusFilter.val(); 

    // Filter pastAppointments based on the selected membership and appointmentType
    const filteredAppointments = past_appointments.filter(appointment => {
      let membershipMatch      = membershipId === 'any' || appointment.membership_id == membershipId;
      let appointmentTypeMatch = appointmentTypeId === 'any' || appointment.appointment_type_id == appointmentTypeId;
      let statusMatch          = statusFilter === 'any' || appointment.status == statusFilter;

      // Check if date filter matches
      const appointmentStartDate = new Date(appointment.start_date);
      const now = new Date();
      let dateMatch;

      switch (dateFilter) {
        case 'last_30_days':
          const oneMonthAgo = new Date();
          oneMonthAgo.setMonth(now.getMonth() - 1);
          dateMatch = appointmentStartDate >= oneMonthAgo;
          break;
        case 'last_90_days':
          const threeMonthsAgo = new Date();
          threeMonthsAgo.setMonth(now.getMonth() - 3);
          dateMatch = appointmentStartDate >= threeMonthsAgo;
          break;
        default:
          dateMatch = true; // default is true
      }

      return membershipMatch && appointmentTypeMatch && dateMatch && statusMatch;
    });

    if (filteredAppointments.length > 1) {
      // Sort the filtered appointments by date
      filteredAppointments.sort(function(a, b) {
        const dateA = new Date(a.start_date)
        const dateB = new Date(b.start_date);
        return dateB - dateA; // For descending order
      });
    }

    // Populate the table with the filtered appointments
    populatePastAppointmentsTable(filteredAppointments);
  }

  function populatePastAppointmentsTable(appointments) {
    // Select the table body where the rows should be inserted
    const $tableBody = $('#ssa-mepr-past-appointments-table-body');

    // Clear the table body
    $tableBody.empty();

    // If there are no past appointments, show a message
    if (appointments.length === 0) {
      const noAppointmentsRow = $(`<tr><td class="ssa-past-table-empty" colspan="3">${translations.noPastAppointments}</td></tr>`);
      $tableBody.append(noAppointmentsRow);
      return;
    }

    // Iterate over the filtered appointments and create a table row for each one
    $.each(appointments, function(index, appointment) {
        const row = $('<tr></tr>');

        const membershipCell = $('<td></td>').text(appointment.membership_title);
        row.append(membershipCell);

        const appointmentTypeCell = $('<td></td>').text(appointment.type_title);
        row.append(appointmentTypeCell);

        const appointmentCell = $('<td></td>').addClass('ssa-mepr_pastAppointmentsCell');
        const formattedDate = $('<span></span>').text(appointment.formatted_start_date);

        // Don't append the view details link for past appointments
        appointmentCell.append(formattedDate);
        row.append(appointmentCell);

        // Append the row to the table body
        $tableBody.append(row);
    });
  }

  /* ------- End Past appointments section ------- */

  function render(){
    renderUpcomingAppointments();
    renderPastAppointments();
  }

  render();

})(jQuery);
