import React, { useCallback, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { LuArrowRight, LuSparkles } from 'react-icons/lu';

import ErrorBanner from '../components/agent-analytics/ErrorBanner';
import { Spinner } from '../components/ui/Spinner';
import ArticleModal from '../components/visibility/ArticleModal';
import GenerateIdeasModal from '../components/visibility/GenerateIdeasModal';
import { toneToBadgeClass } from '../components/visibility/helpers';
import ProblemsList from '../components/visibility/ProblemsList';
import { useAppStateContext } from '../context/user.data.context';
import type {
  ArticleSummary,
  BrandResponse,
  VisibilityProblem,
} from '../service/visibility/visibility.interface';
import {
  listArticles,
  listBrands,
  listProblems,
} from '../service/visibility/visibility.service';

/** How many of the latest generated pages the hub lists. */
const LATEST_PAGES_LIMIT = 6;

/** How many detected problems the hub lists. */
const TOP_PROBLEMS_LIMIT = 5;

/**
 * Map an article status to a badge tone.
 *
 * @param {string} status - Article status as returned by the agent.
 * @return {'success' | 'attention' | 'warning'} Badge tone.
 */
const statusTone = (status: string): 'success' | 'attention' | 'warning' => {
  if (status === 'ready' || status === 'published') return 'success';
  if (status === 'failed') return 'warning';

  return 'attention';
};

/**
 * "Optimized text pages" page under Content Generator. Turns a brief into
 * AI-search-optimized articles by reusing the visibility ideas flow, and
 * doubles as a hub: the main visibility problems worth turning into content,
 * and the latest pages already generated.
 *
 * @return {JSX.Element} The page.
 */
const OptimizedTextPages = (): JSX.Element => {
  const { token, clientId } = useAppStateContext();
  const hasClientCreds = Boolean(token && clientId);

  const [brand, setBrand] = useState<BrandResponse | null>(null);
  const [problems, setProblems] = useState<VisibilityProblem[]>([]);
  const [articles, setArticles] = useState<ArticleSummary[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [modalOpen, setModalOpen] = useState(false);
  const [openArticleId, setOpenArticleId] = useState<string | null>(null);

  const loadAll = useCallback(async (): Promise<void> => {
    if (!hasClientCreds) return;
    setLoading(true);
    setError(null);
    try {
      const brandList = await listBrands(clientId as string, token as string);
      const firstBrand = brandList.brands[0] ?? null;
      setBrand(firstBrand);
      if (!firstBrand) {
        setProblems([]);
        setArticles([]);

        return;
      }
      const [problemList, articleList] = await Promise.all([
        listProblems(
          clientId as string,
          token as string,
          firstBrand.brand_id
        ).catch(() => ({ problems: [] as VisibilityProblem[] })),
        listArticles(clientId as string, token as string, {
          brand_id: firstBrand.brand_id,
          limit: LATEST_PAGES_LIMIT,
        }).catch(() => ({ articles: [] as ArticleSummary[] })),
      ]);
      setProblems(problemList.problems ?? []);
      setArticles((articleList.articles ?? []).slice(0, LATEST_PAGES_LIMIT));
    } catch (err) {
      setError(
        err instanceof Error ? err.message : 'Failed to load optimized pages.'
      );
    } finally {
      setLoading(false);
    }
  }, [hasClientCreds, clientId, token]);

  useEffect(() => {
    void loadAll();
  }, [loadAll]);

  if (!hasClientCreds || loading) {
    return (
      <div className="flex items-center justify-center py-24">
        <Spinner className="w-10 h-10 text-gray-700" />
      </div>
    );
  }

  return (
    <div className="mx-auto w-full max-w-5xl space-y-6 bg-white p-6 md:p-10">
      <div className="space-y-2">
        <div className="flex items-center gap-2">
          <LuSparkles className="h-5 w-5 text-pink-600" aria-hidden />
          <h1 className="text-2xl font-bold tracking-tight text-gray-900">
            Optimized text pages
          </h1>
        </div>
        <p className="text-sm text-gray-500">
          Turn an idea or a brief into AI-search-optimized articles. Describe
          what you want, get a handful of angles back, and generate full pages
          your customers - and the AI engines - actually surface.
        </p>
      </div>

      {error && <ErrorBanner message={error} onRetry={loadAll} />}

      <div className="space-y-4 rounded-xl border border-gray-200 bg-white p-6">
        <ol className="space-y-2 text-sm text-gray-500">
          <li>
            <span className="font-medium text-gray-900">1. Describe it.</span>{' '}
            Paste a brief or upload a .txt / .csv / .docx and edit it however
            you like.
          </li>
          <li>
            <span className="font-medium text-gray-900">
              2. Generate ideas.
            </span>{' '}
            You get 3 to 5 angles (titles, hooks and target keywords).
          </li>
          <li>
            <span className="font-medium text-gray-900">
              3. Pick what to write.
            </span>{' '}
            Generate a full page from any idea - it lands ready to review and
            publish.
          </li>
        </ol>

        <div className="flex flex-wrap items-center gap-3">
          <button
            type="button"
            onClick={() => setModalOpen(true)}
            disabled={!brand}
            className="inline-flex items-center gap-2 rounded-md bg-pink-600 px-4 py-2 text-sm font-medium text-white hover:bg-pink-700 disabled:cursor-not-allowed disabled:opacity-50"
          >
            <LuSparkles className="h-4 w-4" aria-hidden />
            Create optimized text pages
          </button>
          {!brand && (
            <span className="text-xs text-gray-500">
              Set up{' '}
              <Link to="/ai-visibility" className="underline">
                AI Visibility
              </Link>{' '}
              first so we know your brand and catalog.
            </span>
          )}
        </div>
      </div>

      <section className="space-y-3">
        <div className="flex items-center justify-between gap-2">
          <h2 className="text-lg font-semibold text-gray-900">
            Top opportunities
          </h2>
          <Link
            to="/ai-visibility"
            className="inline-flex items-center gap-1 text-xs text-gray-500 underline-offset-2 hover:underline"
          >
            View all in AI Visibility
            <LuArrowRight className="h-3 w-3" aria-hidden />
          </Link>
        </div>
        <p className="text-sm text-gray-500">
          The biggest gaps where AI doesn&apos;t surface you yet - the best
          prompts to target with a new page.
        </p>
        {problems.length > 0 ? (
          <ProblemsList problems={problems.slice(0, TOP_PROBLEMS_LIMIT)} />
        ) : (
          <div className="rounded-xl border border-gray-200 bg-white p-4 text-sm text-gray-500">
            No problems detected this week - nice. Generate pages to widen your
            coverage anyway.
          </div>
        )}
      </section>

      <section className="space-y-3">
        <div className="flex items-center justify-between gap-2">
          <h2 className="text-lg font-semibold text-gray-900">Latest pages</h2>
          <Link
            to="/ai-visibility/contents"
            className="inline-flex items-center gap-1 text-xs text-gray-500 underline-offset-2 hover:underline"
          >
            View all
            <LuArrowRight className="h-3 w-3" aria-hidden />
          </Link>
        </div>
        {articles.length > 0 ? (
          <div className="space-y-2">
            {articles.map(article => (
              <button
                key={article.article_id}
                type="button"
                onClick={() => setOpenArticleId(article.article_id)}
                className="flex w-full items-center justify-between gap-3 rounded-xl border border-gray-200 bg-white px-4 py-3 text-left transition-colors hover:bg-gray-50"
              >
                <div className="min-w-0 flex-1">
                  <p className="truncate text-sm font-medium text-gray-900">
                    {article.title || 'Generated page'}
                  </p>
                  <p className="text-xs text-gray-500">
                    {article.language.toUpperCase()}
                    {article.word_count > 0
                      ? ` - ~${article.word_count} words`
                      : ''}
                  </p>
                </div>
                <span
                  className={`inline-flex shrink-0 items-center rounded-full px-2 py-0.5 text-[10px] font-medium ${toneToBadgeClass(statusTone(article.status))}`}
                >
                  {article.status}
                </span>
              </button>
            ))}
          </div>
        ) : (
          <div className="rounded-xl border border-gray-200 bg-white p-4 text-sm text-gray-500">
            No pages generated yet. Hit &ldquo;Create optimized text
            pages&rdquo; to make your first one.
          </div>
        )}
      </section>

      {brand && (
        <GenerateIdeasModal
          open={modalOpen}
          onOpenChange={setModalOpen}
          clientId={clientId as string}
          token={token as string}
          brandId={brand.brand_id}
          language={brand.language || 'en'}
          onIdeasGenerated={() => {}}
          onArticleStarted={loadAll}
        />
      )}

      <ArticleModal
        open={openArticleId !== null}
        articleId={openArticleId}
        onClose={() => setOpenArticleId(null)}
        clientId={clientId as string}
        token={token as string}
      />
    </div>
  );
};

export default OptimizedTextPages;
