import React, { useState } from 'react';

import EmptyState from '../agent-analytics/EmptyState';
import type {
  ArticleDetailResponse,
  ArticleSummary,
} from '../../service/visibility/visibility.interface';

import ArticleModal from './ArticleModal';
import { countLanguageSiblings, toIsoWeek, toneToBadgeClass } from './helpers';

interface PublishedArticlesListProps {
  /** All articles for the brand; this component filters down to ``published``. */
  articles: ArticleSummary[];
  /** Recomaze client id. */
  clientId: string;
  /** Recomaze JWT. */
  token: string;
  /**
   * Invoked after the merchant flips an article between ``ready`` and
   * ``published`` from inside the modal. Forwarded straight from the parent.
   */
  onArticlePublishedChanged?: (article: ArticleDetailResponse) => void;
}

interface WeekBucket {
  weekIso: string;
  articles: ArticleSummary[];
}

/**
 * Bucket published articles by ISO week (derived from ``published_at``)
 * and return the most-recent week first. Articles without a
 * ``published_at`` should not appear here - they're filtered out before
 * this function runs.
 *
 * @param publishedArticles {ArticleSummary[]} Articles already filtered to ``status === 'published'``.
 * @returns {WeekBucket[]} Per-week buckets sorted most-recent week first; within each bucket, articles are sorted by ``published_at`` descending.
 */
const groupPublishedByWeek = (
  publishedArticles: ArticleSummary[]
): WeekBucket[] => {
  const buckets = new Map<string, ArticleSummary[]>();
  for (const article of publishedArticles) {
    if (!article.published_at) continue;
    const weekIso = toIsoWeek(new Date(article.published_at));
    const existing = buckets.get(weekIso);
    if (existing) {
      existing.push(article);
    } else {
      buckets.set(weekIso, [article]);
    }
  }
  return Array.from(buckets.entries())
    .map(([weekIso, weekArticles]) => ({
      weekIso,
      articles: weekArticles
        .slice()
        .sort((a, b) =>
          (b.published_at ?? '').localeCompare(a.published_at ?? '')
        ),
    }))
    .sort((a, b) =>
      a.weekIso < b.weekIso ? 1 : a.weekIso > b.weekIso ? -1 : 0
    );
};

/**
 * "Published articles" tab - every article whose status is ``"published"``,
 * grouped by the ISO week of ``published_at``. Clicking a row opens it in
 * {@link ArticleModal}; from there the merchant can Unpublish, which lifts
 * the row back to the Recommended tab.
 */
const PublishedArticlesList = ({
  articles,
  clientId,
  token,
  onArticlePublishedChanged,
}: PublishedArticlesListProps): JSX.Element => {
  const [openArticleId, setOpenArticleId] = useState<string | null>(null);

  const publishedArticles = articles.filter(
    article => article.status === 'published'
  );

  if (publishedArticles.length === 0) {
    return (
      <EmptyState message="No published articles yet. Open a ready article and use 'Mark as published' once it's live on your site." />
    );
  }

  const weekBuckets = groupPublishedByWeek(publishedArticles);

  return (
    <>
      <div className="flex flex-col gap-5">
        {weekBuckets.map(bucket => (
          <div key={bucket.weekIso} className="flex flex-col gap-2">
            <h3 className="text-xs font-semibold uppercase tracking-wide text-gray-500">
              {bucket.weekIso}
            </h3>
            <div className="flex flex-col gap-2">
              {bucket.articles.map(article => (
                <div
                  key={article.article_id}
                  className="flex items-center justify-between gap-3 rounded-lg border border-gray-200 bg-white p-3"
                >
                  <div className="min-w-0 flex-1">
                    <h4 className="truncate text-sm font-semibold text-gray-900">
                      {article.title || '(untitled)'}
                    </h4>
                    <div className="mt-1 flex items-center gap-2 text-xs text-gray-500">
                      <span
                        className={`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium ${toneToBadgeClass('success')}`}
                      >
                        Published
                      </span>
                      {countLanguageSiblings(
                        articles,
                        article.translation_group_id
                      ) > 1 && (
                        <span
                          className={`inline-flex items-center rounded-full px-2 py-0.5 text-[10px] font-medium ${toneToBadgeClass('info')}`}
                        >
                          {`Available in ${countLanguageSiblings(
                            articles,
                            article.translation_group_id
                          )} languages`}
                        </span>
                      )}
                      {article.published_at && (
                        <span>
                          {new Date(article.published_at).toLocaleDateString()}
                        </span>
                      )}
                    </div>
                  </div>
                  <button
                    type="button"
                    onClick={() => setOpenArticleId(article.article_id)}
                    className="rounded-md bg-black px-3 py-1.5 text-sm font-medium text-white hover:bg-gray-800"
                  >
                    Open article
                  </button>
                </div>
              ))}
            </div>
          </div>
        ))}
      </div>

      <ArticleModal
        open={openArticleId !== null}
        articleId={openArticleId}
        onClose={() => setOpenArticleId(null)}
        clientId={clientId}
        token={token}
        onPublishedChanged={onArticlePublishedChanged}
      />
    </>
  );
};

export default PublishedArticlesList;
