'use client';

import { Fragment, useRef, useState, type MouseEvent } from 'react';
import type { Insight, InsightCategory, OffsetMeta } from '@/types';
import { getInsights } from '@/lib/api/services/insights';
import { LongArrowRightIcon } from '@/components/icons/common';
import InsightMasonryItem from './InsightMasonryItem';
import { FILTER_ACTIVE_CLASS, FILTER_CLASS, insightFiltersFromCategories, type InsightFilter } from './filters';

interface InsightsBrowserProps {
  initial: Insight[];
  meta: OffsetMeta;
  pageSize: number;
  initialCategory?: InsightCategory;
  categories?: { slug: string; name: string }[];
}

export default function InsightsBrowser({
  initial,
  meta,
  pageSize,
  initialCategory,
  categories,
}: InsightsBrowserProps) {
  const filters: InsightFilter[] = insightFiltersFromCategories(categories);
  const [category, setCategory] = useState<InsightCategory | undefined>(initialCategory);
  const [items, setItems] = useState(initial);
  const [hasMore, setHasMore] = useState(meta.hasMore);
  const [loading, setLoading] = useState(false);
  const requestId = useRef(0);

  const load = async (next: { category?: InsightCategory; offset: number }) => {
    const id = ++requestId.current;
    setLoading(true);
    try {
      const res = await getInsights({ offset: next.offset, limit: pageSize, category: next.category });
      if (id !== requestId.current) return;
      setItems((current) => (next.offset === 0 ? res.data : [...current, ...res.data]));
      setHasMore(Boolean(res.meta?.hasMore));
    } finally {
      if (id === requestId.current) setLoading(false);
    }
  };

  const selectFilter = (value: InsightCategory | 'all') => (e: MouseEvent) => {
    e.preventDefault();
    const nextCategory = value === 'all' ? undefined : value;
    if (nextCategory === category) return;
    setCategory(nextCategory);
    const url = new URL(window.location.href);
    if (nextCategory) url.searchParams.set('category', nextCategory);
    else url.searchParams.delete('category');
    window.history.replaceState(null, '', url);
    load({ category: nextCategory, offset: 0 });
  };

  const activeValue = category ?? 'all';

  return (
    <>
      <div className="d-flex flex-column flex-md-row justify-content-between align-items-xl-center gap-3 gap-md-5 mb-4 mb-md-5">
        <div className="library-filters" id="insightsFilterContainer">
          {filters.map((filter) => (
            <Fragment key={filter.value}>
              <a
                href="#"
                className={filter.value === activeValue ? FILTER_ACTIVE_CLASS : FILTER_CLASS}
                data-filter={filter.value}
                onClick={selectFilter(filter.value)}
              >
                {filter.label}
              </a>{' '}
            </Fragment>
          ))}
        </div>
      </div>

      {items.length === 0 && !loading && <p className="text-md color-content mb-0">No posts in this category yet.</p>}

      {/* Row grid (3 / 2 / 1 columns in insights.css): cards run left to right, newest first, and every card in a
          row takes that row's height, so each row starts and ends level. */}
      <div className="insights-masonry insights-grid" aria-busy={loading}>
        {items.map((insight) => (
          <InsightMasonryItem insight={insight} key={insight.slug} />
        ))}
      </div>

      {hasMore && (
        <div className="d-flex justify-content-center mt-5" id="loadMoreContainer">
          <button
            type="button"
            id="loadMoreBtn"
            className="btn button-style btn-golden w-fit-content mx-auto px-5 py-2 d-flex align-items-center gap-2 fw-600"
            disabled={loading}
            onClick={() => load({ category, offset: items.length })}
          >
            Load More <LongArrowRightIcon className="iconSize-24" />
          </button>
        </div>
      )}
    </>
  );
}
