// modules/PopupDialogSearch.js
import DataTable from "./DataTable.js";

class PopupDialogSearch {
  constructor(config = {}) {
    // === Konfigurasi Dasar ===
    this.containerId = config.containerId || "popup_dialog_container";
    this.targetInputId = config.targetInputId || null;
    this.targetButtonId = config.targetButtonId || null;
    this.clearButtonId = config.clearButtonId || null; // Tambahkan ini
    this.clearCallback = config.clearCallback || null; // Tambahkan ini
    this.columns = config.columns || [];
    this.fetchData = config.fetchData || null;
    this.onPick = config.onPick || null;
    this.title = config.title || "Cari & Pilih Data";
    this.rowsPerPage = config.rowsPerPage || 5;
    this.rowsPerPageOptions = config.rowsPerPageOptions || [5, 10, 25, 50];
    this.additionalElements = config.additionalElements || [];
    this.placeholder = config.placeholder || "Cari...";
    this.emptyMessage = config.emptyMessage || "Tidak ada data";
    this.loadingMessage = config.loadingMessage || "Memuat data...";
    this.pickButtonText = config.pickButtonText || "Pilih";
    this.cancelButtonText = config.cancelButtonText || "Batal";
    this.searchButtonText = config.searchButtonText || "Cari";
    this.filterConfigs = config.filterConfigs || [];

    // === State ===
    this.state = {
      open: false,
      searchText: "",
      rowsPerPage: this.rowsPerPage,
      loading: false,
    };

    // === DOM Elements ===
    this.elements = {};
    this.dataTableInstance = null;

    // === Bind methods ===
    this.init = this.init.bind(this);
    this.open = this.open.bind(this);
    this.close = this.close.bind(this);
    this.handleSearch = this.handleSearch.bind(this);
    this.handlePageChange = this.handlePageChange.bind(this);
    this.handleRowsPerPageChange = this.handleRowsPerPageChange.bind(this);
    this.handlePick = this.handlePick.bind(this);
    this.renderModal = this.renderModal.bind(this);
    this.buildTemplate = this.buildTemplate.bind(this);
    this.attachEventListeners = this.attachEventListeners.bind(this);
    this.initDataTable = this.initDataTable.bind(this);
    this.destroy = this.destroy.bind(this);
  }

  init() {
    let container = document.getElementById(this.containerId);
    if (!container) {
      container = document.createElement("div");
      container.id = this.containerId;
      document.body.appendChild(container);
    }
    this.elements.container = container;

    this.renderModal();
    this.attachTriggerListeners();

    return this;
  }

  attachTriggerListeners() {
    // Target input (click to open)
    if (this.targetInputId) {
      const input = document.getElementById(this.targetInputId);
      if (input) {
        input.addEventListener("click", () => this.open());
        input.addEventListener("focus", () => this.open());
        input.style.cursor = "pointer";
        input.readOnly = true;
      }
    }

    // Target button
    if (this.targetButtonId) {
      const btn = document.getElementById(this.targetButtonId);
      if (btn) {
        btn.addEventListener("click", () => this.open());
      }
    }

    // Clear button
    if (this.clearButtonId && typeof this.clearCallback === "function") {
      const clearBtn = document.getElementById(this.clearButtonId);
      if (clearBtn) {
        clearBtn.addEventListener("click", () => {
          this.clearCallback();
        });
      }
    }

    // Jika ada element dengan data-popup attribute
    document.querySelectorAll("[data-popup]").forEach((el) => {
      const targetId = el.dataset.popup;
      if (targetId === this.targetInputId || targetId === this.containerId) {
        el.addEventListener("click", () => this.open());
      }
    });
  }

  // modules/PopupDialogSearch.js
  // Tambahkan method ini di dalam class PopupDialogSearch

  /**
   * Buka popup secara manual tanpa perlu target button
   * @param {Object} options - Opsi tambahan (opsional)
   * @param {Function} options.onPickOverride - Override callback onPick untuk sementara
   */
  openManually(options = {}) {
    // Jika ada onPickOverride, simpan callback asli dan override
    if (
      options.onPickOverride &&
      typeof options.onPickOverride === "function"
    ) {
      this._originalOnPick = this.onPick;
      this.onPick = options.onPickOverride;
    }

    // Buka popup
    this.open();

    // Reset callback setelah selesai (akan di-reset di close atau setelah pick)
    // Gunakan event listener untuk reset setelah modal tertutup
    const modalEl = this.elements.modal;
    if (modalEl) {
      const resetCallback = () => {
        if (this._originalOnPick) {
          this.onPick = this._originalOnPick;
          this._originalOnPick = null;
        }
        modalEl.removeEventListener("hidden.bs.modal", resetCallback);
      };
      modalEl.addEventListener("hidden.bs.modal", resetCallback);
    }
  }

  renderModal() {
    const container = this.elements.container;
    if (!container) return;

    container.innerHTML = this.buildTemplate();

    // Get element references
    this.elements.modal = document.getElementById(`${this.containerId}_modal`);
    this.elements.dialog = document.querySelector(
      `#${this.containerId}_modal .modal-dialog`,
    );
    this.elements.searchInput = document.getElementById(
      `${this.containerId}_search`,
    );
    this.elements.searchBtn = document.getElementById(
      `${this.containerId}_search_btn`,
    );
    this.elements.tableContainer = document.getElementById(
      `${this.containerId}_table_container`,
    );
    this.elements.paginationContainer = document.getElementById(
      `${this.containerId}_pagination`,
    );
    this.elements.totalInfo = document.getElementById(
      `${this.containerId}_total_info`,
    );
    this.elements.loadingOverlay = document.getElementById(
      `${this.containerId}_loading`,
    );
    this.elements.closeBtn = document.querySelector(
      `#${this.containerId}_modal .btn-close`,
    );
    this.elements.cancelBtn = document.getElementById(
      `${this.containerId}_cancel_btn`,
    );
    this.elements.rowsPerPageSelect = document.getElementById(
      `${this.containerId}_rows_per_page`,
    );
    this.elements.modalTitle = document.getElementById(
      `${this.containerId}_title`,
    );
  }

  // modules/PopupDialogSearch.js

  buildTemplate() {
    const optionsHtml = this.rowsPerPageOptions
      .map(
        (n) =>
          `<option value="${n}" ${n === this.rowsPerPage ? "selected" : ""}>${n}</option>`,
      )
      .join("");

    return `
        <div class="modal fade" id="${this.containerId}_modal" tabindex="-1" role="dialog" data-bs-backdrop="static" data-bs-keyboard="false">
            <div class="modal-dialog modal-dialog-centered modal-xl" role="document">
                <div class="modal-content">
                    <div class="modal-header">
                        <h5 id="${this.containerId}_title" class="modal-title">${this.title}</h5>
                        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                    </div>
                    <div class="modal-body">
                        <!-- Loading -->
                        <div id="${this.containerId}_loading" class="popup-dialog-loading" style="display:none;">
                            <div class="popup-dialog-spinner"></div>
                            <span>${this.loadingMessage}</span>
                        </div>
                        
                        <!-- Table Container - DataTable akan di-render di sini -->
                        <div id="${this.containerId}_table_container" class="popup-dialog-table-wrapper"></div>
                        
                        <!-- Footer -->
                        <div class="popup-dialog-footer">
                            <div class="popup-dialog-rows">
                                <label class="popup-dialog-rows-label">Baris:</label>
                                <select id="${this.containerId}_rows_per_page" class="form-select form-select-sm popup-dialog-rows-select" style="width:auto;">
                                    ${optionsHtml}
                                </select>
                            </div>
                            <div id="${this.containerId}_pagination" class="popup-dialog-pagination">
                                <button class="btn btn-sm btn-outline-secondary popup-dialog-page-btn" data-page="prev" disabled>
                                    <i class="fa fa-chevron-left"></i>
                                </button>
                                <span id="${this.containerId}_total_info" class="popup-dialog-total-info">
                                    1 / 1 (0)
                                </span>
                                <button class="btn btn-sm btn-outline-secondary popup-dialog-page-btn" data-page="next" disabled>
                                    <i class="fa fa-chevron-right"></i>
                                </button>
                            </div>
                            <div>
                                <button id="${this.containerId}_cancel_btn" class="btn btn-secondary popup-dialog-cancel-btn">
                                    ${this.cancelButtonText}
                                </button>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    `;
  }

  attachEventListeners() {
    const {
      modal,
      searchInput,
      searchBtn,
      closeBtn,
      cancelBtn,
      rowsPerPageSelect,
    } = this.elements;

    if (!modal) return;

    modal.addEventListener("click", (e) => {
      if (e.target === modal) this.close();
    });

    if (closeBtn) {
      closeBtn.addEventListener("click", () => this.close());
    }

    if (cancelBtn) {
      cancelBtn.addEventListener("click", () => this.close());
    }

    document.addEventListener("keydown", (e) => {
      if (e.key === "Escape" && this.state.open) {
        this.close();
      }
    });

    if (searchBtn) {
      const newBtn = searchBtn.cloneNode(true);
      searchBtn.parentNode.replaceChild(newBtn, searchBtn);
      this.elements.searchBtn = newBtn;
      newBtn.addEventListener("click", (e) => {
        e.preventDefault();
        this.handleSearch();
      });
    }

    if (rowsPerPageSelect) {
      rowsPerPageSelect.addEventListener("change", () => {
        this.handleRowsPerPageChange(parseInt(rowsPerPageSelect.value));
      });
    }
  }

  open() {
    if (this.state.open) return;

    this.state.open = true;
    this.state.searchText = "";

    // Gunakan Bootstrap Modal
    if (this.elements.modal) {
      // Buat instance Bootstrap Modal
      this.modalInstance = new bootstrap.Modal(this.elements.modal, {
        backdrop: "static",
        keyboard: false,
      });
      this.modalInstance.show();
    }

    if (this.elements.searchInput) {
      this.elements.searchInput.value = "";
      // Fokus setelah modal benar-benar terbuka
      setTimeout(() => {
        if (this.elements.searchInput && this.state.open) {
          this.elements.searchInput.focus();
        }
      }, 300);
    }

    // Attach event listeners
    this.attachEventListeners();
    this.initDataTable();
  }

  close() {
    if (!this.state.open) return;

    this.state.open = false;

    if (this.modalInstance) {
      this.modalInstance.hide();
      this.modalInstance = null;
    }

    if (this.dataTableInstance) {
      this.dataTableInstance.destroy();
      this.dataTableInstance = null;
    }
  }

  handleSearch() {
    if (this.dataTableInstance) {
      // Trigger reload dengan search text
      this.dataTableInstance.reload({
        search: this.state.searchText || "",
      });
    }
  }

  handlePageChange(page) {
    if (this.dataTableInstance) {
      this.dataTableInstance.state.currentPage = page;
      this.dataTableInstance.loadData();
    }
  }

  handleRowsPerPageChange(rows) {
    if (this.dataTableInstance) {
      this.dataTableInstance.state.rowsPerPage = rows;
      this.dataTableInstance.state.currentPage = 1;
      this.dataTableInstance.loadData();
    }
  }

  handlePick(row) {
    if (this.onPick && typeof this.onPick === "function") {
      this.onPick(row);
    }

    if (this.additionalElements && this.additionalElements.length > 0) {
      this.additionalElements.forEach((el) => {
        const target = document.getElementById(el.targetId);
        if (target) {
          const value =
            row[el.columnName] !== undefined ? row[el.columnName] : "";
          target.value = value;
          target.dispatchEvent(new Event("change", { bubbles: true }));
        }
      });
    }

    this.close();
  }

  initDataTable() {
    const container = this.elements.tableContainer;
    if (!container) return;

    // Hapus instance lama
    if (this.dataTableInstance) {
      this.dataTableInstance.destroy();
      this.dataTableInstance = null;
    }

    // Konversi columns ke format DataTable
    const displayColumns = this.columns.map((col) => ({
      columnName: col.columnName,
      displayedName: col.displayedName,
      dataType: "text",
      isShown: true,
    }));

    // Tambahkan kolom aksi di DataTable
    const actionButtons = [
      {
        key: "pick",
        buttonType: "Custom",
        actionType: "Callback",
        label: this.pickButtonText,
        iconClass: '<i class="fa fa-check"></i>',
        callbackFunction: (row) => {
          this.handlePick(row);
        },
      },
    ];

    // Buat formData untuk DataTable
    const formData = new URLSearchParams();

    // Tambahkan filter configs ke DataTable
    const filterConfigs = this.filterConfigs || [];

    // Buat instance DataTable
    this.dataTableInstance = new DataTable({
      containerId: container.id,
      formData: formData,
      displayColumns: displayColumns,
      actionButtons: actionButtons,
      filterConfigs: filterConfigs,
      fetchHelper: async (options) => {
        const { formData: fd } = options;

        // Convert formData ke object
        const params = {};
        fd.forEach((value, key) => {
          params[key] = value;
        });

        console.log("Params from DataTable:", params);

        // Jika ada filters, parse dan kirim langsung
        let filterArray = [];
        if (params.filters) {
          try {
            const parsed = JSON.parse(params.filters);
            if (Array.isArray(parsed)) {
              // Flatten jika perlu
              const first = parsed[0];
              if (
                Array.isArray(first) &&
                first.length === 3 &&
                Array.isArray(first[1])
              ) {
                filterArray = parsed.map((f) => f[1]);
              } else {
                filterArray = parsed;
              }
            }
          } catch (e) {
            filterArray = [];
          }
        }

        // === KIRIM KE fetchData TANPA MODIFIKASI BERLEBIH ===
        const result = await this.fetchData({
          search: params.search || "",
          page: parseInt(params.page_number) || 1,
          rowsPerPage: parseInt(params.rows_per_page) || this.rowsPerPage,
          filters: filterArray, // Kirim sebagai array
        });

        return {
          result: {
            Status: 1,
            list_data: result.data || [],
            total_rows: result.totalData || 0,
            total_page: result.totalPage || 1,
            PKColumn: this.columns[0]?.columnName || "ID",
            orderColumns: this.columns.map((c) => c.columnName),
          },
        };
      },
      onAddNew: null,
      addNewLabel: "",
      defaultRowsPerPage: this.rowsPerPage,
      rowsPerPageOptions: this.rowsPerPageOptions,
      allowFilter: this.filterConfigs.length > 0,
      allowOrder: false,
      allowPaging: true,
      allowExport: false,
      rowSelection: { enabled: false },
      defaultOrderDirection: "ASC",
    });

    // Override render untuk menambahkan class khusus
    this.dataTableInstance.render();
  }

  destroy() {
    this.close();
    if (this.elements.container) {
      this.elements.container.innerHTML = "";
    }
  }
}

export default PopupDialogSearch;
