<?php

namespace GriffinForms\Admin\App\Html\Widgets\RightSidebar;

final class FieldSelection extends \GriffinForms\Admin\App\Html\Widgets\RightSidebar\Format
{
  
  public function getHtml()
  {
    $this->categoryTabs();
    $this->categoryTabPanes();
  }

  private function categoryTabs()
  {
    $tabs = array(
      array('id' => $this->getHtmlId('field-types-tab'), 'label' => __('Field Types', 'griffinforms-form-builder')),
      array('id' => $this->getHtmlId('reusable-fields-tab'), 'label' => __('Reusable Fields', 'griffinforms-form-builder'))
    );

    $bs_tabs = \GriffinForms\Admin\App\Html\Elements\BsTabs::getInstance();
    $bs_tabs->navTabs($tabs);
  }

  private function categoryTabPanes()
  {
    echo '<div class="tab-content p-3" id="' . esc_attr($this->getHtmlId('fieldselection-tab-content')) . '">';
    $this->fieldTypesPane();
    $this->reusableFieldsPane();
    echo '</div>';
  }

  private function fieldTypesPane()
  {
    echo '<div class="tab-pane fade show active small px-" id="' . esc_attr($this->getHtmlId('field-types-tab-pane')) . '" role="tabpanel" tabindex="0">';
    $this->commonFieldTypes();
    $this->advancedFieldTypes();
    echo '</div>';
  }

  private function commonFieldTypes()
  {
    echo '<div class="fw-bold my-2 text-uppercase" style="font-size: 10px;">';
    esc_html_e('Common Fields', 'griffinforms-form-builder');
    echo '</div>';
    echo '<div class="row g-2">';
    $this->fieldTypePill('inputtext', __('Single-Line Text', 'griffinforms-form-builder'));
    $this->fieldTypePill('inputnumber', __('Number', 'griffinforms-form-builder'));
    $this->fieldTypePill('inputemail', __('Email', 'griffinforms-form-builder'));
    $this->fieldTypePill('inputphone', __('Phone Number', 'griffinforms-form-builder'));
    $this->fieldTypePill('inputurl', __('URL', 'griffinforms-form-builder'));
    $this->fieldTypePill('selectfield', __('Dropdown', 'griffinforms-form-builder'));
    echo '</div>';
  }

  private function advancedFieldTypes()
  {
    echo '<div class="fw-bold mt-4 mb-2 text-uppercase" style="font-size: 10px;">';
    esc_html_e('Advanced Fields', 'griffinforms-form-builder');
    echo '</div>';
    echo '<div class="row g-2">';
    $this->fieldTypePill('inputdate', __('Date', 'griffinforms-form-builder'));
    $this->fieldTypePill('inputradio', __('Radio', 'griffinforms-form-builder'));
    $this->fieldTypePill('inputcheckbox', __('Checkbox', 'griffinforms-form-builder'));
    $this->fieldTypePill('textarea', __('Multi-Line Text', 'griffinforms-form-builder'));
    echo '</div>';
  }

  private function fieldTypePill($type, $label)
  {
    echo '<div class="col-md-6">';
    echo '<div class="gf-app-new-field-pill gf-app-field-pill text-start bg-light py-3 px-3 rounded-2 d-flex justify-content-start align-items-center" ';
    echo 'id="' . esc_attr($this->getHtmlId($type . '-field-pill')) . '" ';
    echo 'data-gf-fieldtype="' . esc_attr($type) . '">';
    $this->fieldTypeIcon($type);
    echo '<div class="small ms-2" style="font-weight:500; letter-spacing: 0.5px;">' . esc_html($label) . '</div>';
    echo '<div class="ms-2 spinner-border spinner-border-sm visually-hidden" role="status">';
    echo '<span class="visually-hidden">Loading...</span>';
    echo '</div>';
    echo '</div>';
    echo '</div>';
  }

  private function reusableFieldsPane()
  {
    echo '<div class="tab-pane fade overflow-y-auto" id="' . esc_attr($this->getHtmlId('reusable-fields-tab-pane')) . '" role="tabpanel" tabindex="0" style="height:auto">';
    echo '<div class="row g-3"></div>';
    echo '</div>';
  }

  public function getJs()
  {
    $this->setReusableFieldsHeightJs();
    $this->toggleFieldSelectionJs();
    $this->makeFieldPillsDraggableJs();
    $this->getReusableFieldsJs();
  }

  private function setReusableFieldsHeightJs()
  {
    echo '
    const tabEl = document.querySelector("#griffinforms-app-fieldselection-reusable-fields-tab");
    tabEl.addEventListener("shown.bs.tab", event => {
      setReusableFieldsHeight();
    })
    
    function setReusableFieldsHeight() {
      let totalHeight = $("#griffinforms-app-rightsidebar").height();
      $("#griffinforms-app-fieldselection-reusable-fields-tab-pane").height(totalHeight);
    }
    ';
  }

  private function toggleFieldSelectionJs()
  {
    echo '
    document.addEventListener("item-selected", () => {

      let itemType = $("[data-gf-selected=true]").attr("data-gf-itemtype")
      
      if (itemType === "rowcolumn" || itemType === "pagerow") {
        return;
      }

      $("#griffinforms-app-rightsidebar-field-selection").hide();
      });
    
    document.addEventListener("item-deselected", () => {
      $("#griffinforms-app-rightsidebar-field-selection").show();
    });
    ';
  }

  private function makeFieldPillsDraggableJs()
  {
    echo '
    makeFieldPillsDraggable();

    function makeFieldPillsDraggable() {
      $(".gf-app-field-pill").draggable({
        appendTo: "#griffinforms-app-rightsidebar-field-selection",
        cursor: "crosshair",
        helper: "clone",
        connectToSortable: "[data-gf-itemtype=rowcolumn]",
        zIndex: 999999999,
        start: function(event, ui) {
          $(ui.helper).addClass("shadow bg-white");
          $(".griffinforms-app-formlayout-rowcolumn").addClass("griffinforms-fe-droppable");
          $(ui.helper).width("250");
        },
        stop: function(event, ui) {
          $(ui.helper).removeClass("shadow");
          $(ui.helper).addClass("w-100");
          $(".griffinforms-app-formlayout-rowcolumn").removeClass("griffinforms-fe-droppable");
        }
      });
    }
    ';
  }

  private function getReusableFieldsJs()
  {
    if (empty($_GET['form_id'])) {
      echo '
      const form_id = $(".griffinforms-app-formlayout-form").attr("data-gf-itemid");
      ';
    } else {
      echo '
      const form_id = ' . absint($_GET['form_id']) . ';';
    }

    echo '
    $("#' . esc_js($this->getHtmlId('reusable-fields-tab')) . '").click(function() {
      getReusableFields(limit = 20);
    });

    document.addEventListener("form-html-received", () => {
      getReusableFields();
    });

    function getReusableFields(limit = 20) {
      
    const fieldData = {
          "action": "getReusableFields",
          "form_id": form_id,
          "limit": limit
      };

      $.post(ajaxurl, fieldData, function(response) {
          response = JSON.parse(response);
          
          if (response.success) {
            $("#' . esc_js($this->getHtmlId('reusable-fields-tab-pane')) . '").children(".row").html(response.html);
            makeFieldPillsDraggable();
            setReusableFieldsHeight();
          } else {
            statusbarMsg("failure", response.msg);
          }

      });
    }
    ';
  }

  /**
   * Returns the HTML notice indicating that there are no reusable fields.
   *
   * @return string
   */
  private function getNoReusableFieldsNotice() {
      $notice  = '<div class="col-12">';
      $notice .= '<div class="gf-notice mt-4">';
      $notice .= __('No reusable fields available or all available fields are already used in this form. (Reusable fields are fields that you can create once and reuse in multiple forms.)', 'griffinforms-form-builder');
      $notice .= '</div>';
      $notice .= '</div>';
      return $notice;
  }

  /**
  * Retrieves reusable fields via an AJAX call.
  *
  * If there are no reusable fields, it returns a notice with instructions.
  *
  * @return void
  */
  public function getReusableFields()
  {
    $limit = isset($_POST['limit']) ? sanitize_text_field(wp_unslash($_POST['limit'])) : 0;
    $fields = $this->sql->getReusableFields($limit);

    if ($fields === false) {
        global $wpdb;
        $this->response['success'] = false;
        $this->response['msg'] = $wpdb->last_error;
    } else {
        $form_id = isset($_POST['form_id']) ? sanitize_text_field(wp_unslash($_POST['form_id'])) : 0;
        $html = $this->reusableFieldsHtml($fields, $form_id);
        $this->response['success'] = true;
        $this->response['msg'] = __('Fields updated successfully.', 'griffinforms-form-builder');

        if (empty($html['html'])) {
            $this->response['html'] = $this->getNoReusableFieldsNotice();
        } else {
            $this->response['html'] = $html['html'];
        }
    }

    echo wp_json_encode($this->response);
    wp_die();
  }

  /**
   * Generates the HTML for displaying reusable field pills.
   *
   * Filters out fields already used in the form to avoid duplicates.
   *
   * @param array $fields  List of available reusable fields.
   * @param int|string $form_id  Current form ID to check existing fields against.
   * @return array  Contains generated HTML and list of field IDs.
   */
  private function reusableFieldsHtml($fields, $form_id)
  {
    $html = '';
    $field_ids = [];

    $existing_fields = $this->sql->fieldsInForm($form_id);

    foreach ($fields as $field) {
        $field_ids[] = $field->id;
        $css_class = 'gf-app-reusable-field-pill gf-app-field-pill';

        // Skip rendering if the field is already used in the form.
        // Ensure strict type-safe comparison by casting both to string.
        if (!in_array((string) $field->id, array_map('strval', $existing_fields), true)) {
            if (empty($field->name)) {
                $field->name = $this->config->getFriendlyName('field') . '-' . $field->id;
            }

            $html .= '<div class="col-md-6">';
            $html .= '<div class="' . esc_attr($css_class) . ' text-start bg-light py-3 px-3 rounded-1 d-flex justify-content-start align-items-center" ';
            $html .= 'id="' . esc_attr($this->getHtmlId($field->id . '-field-pill')) . '" ';
            $html .= 'data-gf-itemid="' . esc_attr($field->id) . '">';

            // Place the icon inside the pill container
            ob_start();
            $this->fieldTypeIcon($field->field_type);
            $html .= ob_get_clean();

            $html .= '<div class="small ms-2" style="font-weight:500; letter-spacing: 0.5px;">' . esc_html($field->name) . '</div>';
            $html .= '<div class="ms-2 spinner-border spinner-border-sm visually-hidden" role="status">';
            $html .= '<span class="visually-hidden">Loading...</span>';
            $html .= '</div>';
            $html .= '</div>';
            $html .= '</div>';
        }
    }

    return ['html' => $html, 'field_ids' => $field_ids];
  }

  private function fieldTypeIcon($field_type)
  {
      static $checked_icons = [];

      $icon_file = 'griffinforms_icon_' . $field_type . '.svg';
      $icon_path = $this->config->getRootPath() . 'admin/images/field-icons/' . $icon_file;
      $icon_url  = $this->config->getRootUrl() . 'admin/images/field-icons/' . $icon_file;
      $fallback_url = $this->config->getRootUrl() . 'admin/images/field-icons/griffinforms_icon_fallback.svg';

      // Check and cache whether the icon file exists
      if (!isset($checked_icons[$field_type])) {
          $checked_icons[$field_type] = file_exists($icon_path);
      }

      $final_url = $checked_icons[$field_type] ? $icon_url : $fallback_url;

      echo '<img height="18" src="' . esc_url($final_url) . '" alt="' . esc_attr($field_type) . '" class="gf-app-field-icon" />';
  }

  public function __construct()
  {
      $this->setAll();
      add_action('wp_ajax_getReusableFields', array($this, 'getReusableFields'));
  }
}
