
// DOM Elements
const DOM = {
  container: document.getElementById("card-container"),
  pagination: document.getElementById("pagination"),
  searchInput: document.getElementById("search-input"),
  loading: document.getElementById("loading-indicator"),
  resultCount: document.getElementById("result-count")
};

// Configuration
const CONFIG = {
  url: window.location.href.replace(/\/$/, "") + "/api/posts",
  postsPerPage: 12,
  maxVisiblePages: 5,
  searchDelay: 300
};

// Application State
const state = {
  allPosts: [],
  filteredPosts: [],
  currentPage: 1,
  totalPages: 1,
  searchTerm: ""
};

// Utility Functions
const utils = {
  debounce: (func, delay) => {
    let timeout;
    return (...args) => {
      clearTimeout(timeout);
      timeout = setTimeout(() => func.apply(this, args), delay);
    };
  },

  normalizePost: post => ({
    ...post,
    _autor: post.autor.toLowerCase(),
    _title: post.title.toLowerCase(),
    _preview: post.preview.toLowerCase()
  }),

  saveState: () => {
    const searchState = {
      page: state.currentPage,
      term: state.searchTerm
    };
    localStorage.setItem("searchState", JSON.stringify(searchState));
  },

  loadState: () => {
    const savedState = JSON.parse(localStorage.getItem("searchState")) || {};
    state.currentPage = savedState.page || 1;
    state.searchTerm = savedState.term || "";
    DOM.searchInput.value = state.searchTerm;
  },

  animateCards: () => {
    const cards = document.querySelectorAll('.card-wrapper');
    let index = 0;

    const animate = () => {
      if (index < cards.length) {
        cards[index].classList.add('visible');
        index++;
        requestAnimationFrame(animate);
      }
    };

    requestAnimationFrame(animate);
  }
};

// Rendering Functions
const render = {
  showLoading: () => {
    DOM.loading.style.display = 'block';
    DOM.container.style.opacity = '0.5';
  },

  hideLoading: () => {
    DOM.loading.style.display = 'none';
    DOM.container.style.opacity = '1';
  },

  posts: () => {
    DOM.container.innerHTML = "";

    const start = (state.currentPage - 1) * CONFIG.postsPerPage;
    const end = start + CONFIG.postsPerPage;
    const postsToShow = state.filteredPosts.slice(start, end);

    if (postsToShow.length === 0) {
      DOM.container.innerHTML = `
        <div class="col-12 text-center py-5">
          <h4>No se encontraron resultados</h4>
          <p class="text-muted">Intenta con otros términos de búsqueda</p>
        </div>
      `;
      return;
    }

    const fragment = document.createDocumentFragment();

    postsToShow.forEach(post => {
      const imgSrc = post.first_img || 'static/y_img/other/no_img.png';
      const dateUpdate = post.author_updated ? `<i class="bi bi-arrow-repeat"></i> ${post.author_updated}<br>` : "";

      const card = document.createElement("div");
      card.className = "col card-wrapper";
      card.innerHTML = `
       <div class="card h-100">
          <a href="/blog/${post.id}" class="stretched-link" onclick="utils.saveState()">
            <img src="${imgSrc}" class="card-img-top" alt="${post.title}" loading="lazy">
          </a>
          <div class="card-body d-flex flex-column">
            <div class="mb-3">
              <h5 class="card-title">${post.title}</h5>
              <small class="text-muted d-block mt-2">
                <i class="bi bi-file-person-fill"></i> ${post.autor}<br>
                <i class="bi bi-calendar-week"></i> ${post.author_creation}<br>
                ${dateUpdate}
                <i class="bi bi-clock"></i> ${post.read_time_min} min(s) de lectura. 
              </small>
              <p class="card-text mt-2">${post.preview}...</p>
            </div>
          </div>
        </div>
      `;
      fragment.appendChild(card);
    });

    DOM.container.appendChild(fragment);
    utils.animateCards();
  },

  pagination: () => {
    DOM.pagination.innerHTML = "";
    state.totalPages = Math.ceil(state.filteredPosts.length / CONFIG.postsPerPage);
    DOM.resultCount.textContent = state.filteredPosts.length;

    const pageItem = (page, label = null, disabled = false, active = false) => {
      const li = document.createElement("li");
      li.className = `page-item ${disabled ? 'disabled' : ''} ${active ? 'active' : ''}`;
      const a = document.createElement("a");
      a.className = "page-link";
      a.href = "#";
      a.textContent = label || page;
      if (!disabled && !active) {
        a.addEventListener("click", (e) => {
          e.preventDefault();
          state.currentPage = page;
          utils.saveState();
          render.updateView();
        });
      }
      li.appendChild(a);
      return li;
    };

    const pageDots = () => {
      const li = document.createElement("li");
      li.className = "page-item disabled";
      li.innerHTML = `<span class="page-link">...</span>`;
      return li;
    };

    // Botón anterior
    if (state.currentPage > 1) {
      DOM.pagination.appendChild(pageItem(state.currentPage - 1, "«"));
    }

    const startPage = Math.max(1, state.currentPage - Math.floor(CONFIG.maxVisiblePages / 2));
    const endPage = Math.min(state.totalPages, startPage + CONFIG.maxVisiblePages - 1);

    if (startPage > 1) {
      DOM.pagination.appendChild(pageItem(1));
      if (startPage > 2) DOM.pagination.appendChild(pageDots());
    }

    for (let i = startPage; i <= endPage; i++) {
      DOM.pagination.appendChild(pageItem(i, null, false, i === state.currentPage));
    }

    if (endPage < state.totalPages) {
      if (endPage < state.totalPages - 1) DOM.pagination.appendChild(pageDots());
      DOM.pagination.appendChild(pageItem(state.totalPages));
    }

    // Botón siguiente
    if (state.currentPage < state.totalPages) {
      DOM.pagination.appendChild(pageItem(state.currentPage + 1, "»"));
    }
  },

  updateView: () => {
    render.posts();
    render.pagination();
    window.scrollTo({ top: 0, behavior: 'smooth' });
  }
};

// Search Functionality
const search = {
  filterPostsByTerm: (posts, term) => {
    if (!term) return [...posts];
    const loweredTerm = term.toLowerCase();
    return posts.filter(post =>
      post._autor.includes(loweredTerm) ||
      post._title.includes(loweredTerm) ||
      post._preview.includes(loweredTerm)
    );
  },

  filterPosts: term => {
    const newSearchTerm = term.toLowerCase();
    // if (newSearchTerm === state.searchTerm) return;
    if (newSearchTerm === state.searchTerm && newSearchTerm !== "") return;

    state.searchTerm = newSearchTerm;
    state.filteredPosts = search.filterPostsByTerm(state.allPosts, state.searchTerm);
    state.currentPage = 1;
    render.updateView();
  },

  init: () => {
    DOM.searchInput.addEventListener("input", utils.debounce(() => {
      search.filterPosts(DOM.searchInput.value);
    }, CONFIG.searchDelay));
  }
};

// Initialization
const init = {
  loadPosts: () => {
    render.showLoading();
    fetch(CONFIG.url)
      .then(response => {
        if (!response.ok) throw new Error('Error en la red');
        return response.json();
      })
      .then(data => {
        state.allPosts = data.map(utils.normalizePost);
        utils.loadState();
        state.filteredPosts = search.filterPostsByTerm(state.allPosts, state.searchTerm);
        state.totalPages = Math.ceil(state.filteredPosts.length / CONFIG.postsPerPage);
        state.currentPage = Math.min(state.currentPage, state.totalPages || 1);
        render.updateView();
      })
      .catch(error => {
        console.error('Error:', error);
        DOM.container.innerHTML = `
          <div class="col-12 text-center py-5">
            <h4>Error al cargar los posts</h4>
            <p class="text-muted">Por favor intenta recargar la página</p>
          </div>
        `;
      })
      .finally(() => {
        render.hideLoading();
      });
  }
};

document.addEventListener("DOMContentLoaded", () => {
  init.loadPosts();
  search.init();
});


  // limpiar buscador
  document.getElementById('clear-btn').addEventListener('click', function () {
    const input = document.getElementById('search-input');
    input.value = '';
    state.searchTerm = '';  // resetear el estado
    state.filteredPosts = [...state.allPosts];  // mostrar todo de nuevo
    state.currentPage = 1;
    render.updateView();  // actualizar la vista
    localStorage.removeItem("searchState"); // opcional: limpiar localStorage
  });
  