import React, {
  ReactElement,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import Head from 'next/head';
import {
  mdiCheckCircleOutline,
  mdiDownloadBoxOutline,
  mdiFileDocumentOutline,
  mdiFileExportOutline,
  mdiFileSwapOutline,
  mdiHistory,
  mdiLinkVariant,
} from '@mdi/js';
import BaseButton from '../components/BaseButton';
import BaseIcon from '../components/BaseIcon';
import CardBox from '../components/CardBox';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import LayoutAuthenticated from '../layouts/Authenticated';
import { getPageTitle } from '../config';
import { fetch as fetchArticles } from '../stores/articles/articlesSlice';
import { useAppDispatch, useAppSelector } from '../stores/hooks';
import {
  applyAffiliateReplacements,
  detectAffiliateLinks,
  type AffiliateReplacementGroup,
  type DetectedContentLink,
} from '../helpers/affiliateLinks';

type SourceArticleRecord = {
  id?: string;
  title?: string | null;
  slug?: string | null;
  status?: string | null;
  excerpt?: string | null;
  content_html?: string | null;
  content_markdown?: string | null;
  source_url?: string | null;
  published_at?: string | null;
  createdAt?: string | null;
  updatedAt?: string | null;
};

type Article = {
  id: string;
  title: string;
  status: string;
  source: string;
  readingTime: string;
  html: string;
};

type ExportFormat = 'wordpress' | 'html' | 'markdown';

type ExportRecord = {
  id: string;
  articleTitle: string;
  format: ExportFormat;
  createdAt: string;
  replacements: number;
  fileName: string;
  preview: string;
};

const sampleArticles: Article[] = [
  {
    id: 'portable-power-stations',
    title: '7 Portable Power Station Uses for Weekend Travelers',
    status: 'Sample article',
    source: 'Fallback sample',
    readingTime: '5 min read',
    html: `<h1>7 Portable Power Station Uses for Weekend Travelers</h1>
<p>Weekend travelers are using compact power stations to keep phones, cameras, and small appliances running without hunting for outlets.</p>
<p>Our top recommendation is this <a href="https://www.amazon.com/portable-power-station/dp/B0POWER123?tag=publisher-20">portable power station</a> because it balances capacity, size, and price.</p>
<h2>Pair it with solar</h2>
<p>For longer trips, add a folding <a href="https://www.amazon.com/folding-solar-panel/dp/B0SOLAR456?tag=publisher-20">solar charging panel</a> to extend runtime while camping or tailgating.</p>`,
  },
  {
    id: 'home-office-upgrades',
    title: 'Home Office Upgrades That Make Content Creators Faster',
    status: 'Sample article',
    source: 'Fallback sample',
    readingTime: '4 min read',
    html: `<h1>Home Office Upgrades That Make Content Creators Faster</h1>
<p>A focused creator desk can reduce editing friction and make every recording session feel easier.</p>
<p>Start with an adjustable <a href="https://shareasale.com/r.cfm?b=123456&u=999999&m=77777&urllink=https%3A%2F%2Fmerchant.example%2Fdesk-light">LED desk light</a> for consistent video quality.</p>
<p>Then upgrade voiceovers with a plug-and-play <a href="https://merchant.example/usb-mic?aff=publisher-demo">USB microphone</a> that works with most recording apps.</p>`,
  },
];

const formatLabels: Record<ExportFormat, string> = {
  wordpress: 'WordPress WXR/XML',
  html: 'HTML',
  markdown: 'Markdown',
};

const historyStorageKey = 'affiliate-export-studio-history';

const escapeXml = (value: string) =>
  value
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&apos;');

const stripTags = (value: string) =>
  value
    .replace(/<[^>]*>/g, ' ')
    .replace(/\s+/g, ' ')
    .trim();

const escapeHtml = (value: string) =>
  value
    .replace(/&/g, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');

const markdownLinkPattern =
  /\[([^\]]+)]\((<[^>]+>|[^)\s]+)(?:\s+["'][^"']*["'])?\)/g;

const convertInlineMarkdownLinks = (value: string) => {
  const parts: string[] = [];
  let lastIndex = 0;

  value.replace(markdownLinkPattern, (match, label, url, index) => {
    parts.push(escapeHtml(value.slice(lastIndex, index)));
    parts.push(
      `<a href="${escapeHtml(url.replace(/^<|>$/g, ''))}">${escapeHtml(
        label,
      )}</a>`,
    );
    lastIndex = index + match.length;
    return match;
  });

  parts.push(escapeHtml(value.slice(lastIndex)));

  return parts.join('');
};

const buildHtmlFromMarkdown = (markdown: string) =>
  markdown
    .split(/\n{2,}/)
    .map((block) => {
      const trimmedBlock = block.trim();

      if (!trimmedBlock) return '';

      if (trimmedBlock.startsWith('## ')) {
        return `<h2>${convertInlineMarkdownLinks(
          trimmedBlock.replace(/^##\s+/, ''),
        )}</h2>`;
      }

      if (trimmedBlock.startsWith('# ')) {
        return `<h1>${convertInlineMarkdownLinks(
          trimmedBlock.replace(/^#\s+/, ''),
        )}</h1>`;
      }

      const lines = trimmedBlock.split('\n');
      const isList = lines.every((line) => /^[-*]\s+/.test(line.trim()));

      if (isList) {
        return `<ul>${lines
          .map(
            (line) =>
              `<li>${convertInlineMarkdownLinks(
                line.trim().replace(/^[-*]\s+/, ''),
              )}</li>`,
          )
          .join('')}</ul>`;
      }

      return `<p>${convertInlineMarkdownLinks(trimmedBlock).replace(
        /\n/g,
        '<br />',
      )}</p>`;
    })
    .filter(Boolean)
    .join('\n');

const getStringValue = (value?: string | null) =>
  typeof value === 'string' ? value.trim() : '';

const getSourceLabel = (sourceUrl?: string | null) => {
  const trimmedSourceUrl = getStringValue(sourceUrl);

  if (!trimmedSourceUrl) return 'Saved article';

  try {
    return new URL(trimmedSourceUrl).hostname;
  } catch (error) {
    console.error('Failed to parse article source URL', {
      sourceUrl: trimmedSourceUrl,
      error,
    });
    return trimmedSourceUrl;
  }
};

const formatStatusLabel = (status?: string | null) => {
  const trimmedStatus = getStringValue(status);

  if (!trimmedStatus) return 'Unspecified';

  return trimmedStatus.replace(/_/g, ' ');
};

const estimateReadingTime = (html: string) => {
  const wordCount = stripTags(html).split(/\s+/).filter(Boolean).length;
  const minutes = Math.max(1, Math.ceil(wordCount / 200));

  return `${minutes} min read`;
};

const getArticleHtml = (record: SourceArticleRecord) => {
  const html = getStringValue(record.content_html);

  if (html) return html;

  const markdown = getStringValue(record.content_markdown);

  if (markdown) return buildHtmlFromMarkdown(markdown);

  const title = getStringValue(record.title) || 'Untitled article';
  const excerpt = getStringValue(record.excerpt);

  return `<h1>${escapeHtml(title)}</h1>${
    excerpt ? `<p>${escapeHtml(excerpt)}</p>` : ''
  }`;
};

const normalizeArticleRecord = (
  record: SourceArticleRecord,
  index: number,
): Article | null => {
  const html = getArticleHtml(record);
  const title = getStringValue(record.title) || `Article ${index + 1}`;

  if (!stripTags(html) && !title) return null;

  return {
    id:
      getStringValue(record.id) ||
      getStringValue(record.slug) ||
      `article-${index}`,
    title,
    status: formatStatusLabel(record.status),
    source: getSourceLabel(record.source_url),
    readingTime: estimateReadingTime(html),
    html,
  };
};

const slugify = (value: string) =>
  value
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-|-$/g, '');

const htmlAnchorPattern =
  /<a\b[^>]*?\bhref\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s>]+))[^>]*>([\s\S]*?)<\/a>/gi;

const buildMarkdown = (html: string) =>
  html
    .replace(
      htmlAnchorPattern,
      (_match, doubleQuoted, singleQuoted, bareUrl, label) => {
        const href = doubleQuoted || singleQuoted || bareUrl || '';
        return `[${stripTags(label)}](${href})`;
      },
    )
    .replace(/<h1>(.*?)<\/h1>/gis, '# $1\n\n')
    .replace(/<h2>(.*?)<\/h2>/gis, '## $1\n\n')
    .replace(/<li>(.*?)<\/li>/gis, '- $1\n')
    .replace(/<\/ul>/gi, '\n')
    .replace(/<ul>/gi, '')
    .replace(/<p>(.*?)<\/p>/gis, '$1\n\n')
    .replace(/<br\s*\/?>(\n)?/gi, '\n')
    .replace(/<[^>]*>/g, '')
    .replace(/\n{3,}/g, '\n\n')
    .trim();

const buildWordPressXml = (
  article: Article,
  html: string,
) => `<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0" xmlns:excerpt="http://wordpress.org/export/1.2/excerpt/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wp="http://wordpress.org/export/1.2/">
  <channel>
    <title>LinkLift Studio Export</title>
    <wp:wxr_version>1.2</wp:wxr_version>
    <item>
      <title>${escapeXml(article.title)}</title>
      <wp:post_type>post</wp:post_type>
      <wp:status>draft</wp:status>
      <content:encoded><![CDATA[${html}]]></content:encoded>
    </item>
  </channel>
</rss>`;

const getExtension = (format: ExportFormat) => {
  if (format === 'wordpress') return 'xml';
  if (format === 'markdown') return 'md';
  return 'html';
};

const createDownload = (
  fileName: string,
  content: string,
  format: ExportFormat,
) => {
  const mimeType = format === 'wordpress' ? 'application/xml' : 'text/plain';
  const blob = new Blob([content], { type: `${mimeType};charset=utf-8` });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = fileName;
  document.body.appendChild(anchor);
  anchor.click();
  anchor.remove();
  URL.revokeObjectURL(url);
};

const getUniqueLinksByUrl = (links: DetectedContentLink[]) => {
  const seenUrls = new Set<string>();

  return links.filter((link) => {
    if (seenUrls.has(link.originalUrl)) {
      return false;
    }

    seenUrls.add(link.originalUrl);
    return true;
  });
};

const getTagPlaceholder = (group: AffiliateReplacementGroup) => {
  if (group.parameter.toLowerCase() === 'tag') {
    return 'yourstore-20';
  }

  if (group.parameter.toLowerCase().includes('sub')) {
    return 'buyer-sub-id';
  }

  return 'buyer-affiliate-id';
};

const ExportStudio = () => {
  const dispatch = useAppDispatch();
  const hasRequestedArticles = useRef(false);
  const { articles, loading: articlesLoading } = useAppSelector(
    (state) => state.articles,
  );
  const { currentUser } = useAppSelector((state) => state.auth);
  const [selectedArticleId, setSelectedArticleId] = useState('');
  const [hasAttemptedArticleLoad, setHasAttemptedArticleLoad] = useState(false);
  const [articleLoadError, setArticleLoadError] = useState('');
  const [format, setFormat] = useState<ExportFormat>('wordpress');
  const [tagReplacements, setTagReplacements] = useState<
    Record<string, string>
  >({});
  const [urlOverrides, setUrlOverrides] = useState<Record<string, string>>({});
  const [history, setHistory] = useState<ExportRecord[]>([]);
  const [selectedExportId, setSelectedExportId] = useState<string | null>(null);
  const [successMessage, setSuccessMessage] = useState('');
  const [errorMessage, setErrorMessage] = useState('');

  const articleRows = Array.isArray(articles) ? articles : [];
  const apiArticles = useMemo(
    () =>
      articleRows
        .map((record, index) =>
          normalizeArticleRecord(record as SourceArticleRecord, index),
        )
        .filter((article): article is Article => Boolean(article)),
    [articleRows],
  );
  const articlesForStudio =
    apiArticles.length > 0 ? apiArticles : sampleArticles;
  const isUsingFallbackArticles =
    hasAttemptedArticleLoad && apiArticles.length === 0;

  const selectedArticle = useMemo(
    () =>
      articlesForStudio.find((article) => article.id === selectedArticleId) ??
      articlesForStudio[0] ??
      sampleArticles[0],
    [articlesForStudio, selectedArticleId],
  );

  const affiliateDetection = useMemo(
    () => detectAffiliateLinks(selectedArticle.html),
    [selectedArticle.html],
  );
  const detectedGroups = affiliateDetection.groups;
  const detectedLinks = affiliateDetection.links;
  const uniqueDetectedLinks = useMemo(
    () => getUniqueLinksByUrl(detectedLinks),
    [detectedLinks],
  );

  const customizedHtml = useMemo(
    () =>
      applyAffiliateReplacements(
        selectedArticle.html,
        detectedLinks,
        tagReplacements,
        urlOverrides,
      ),
    [detectedLinks, selectedArticle.html, tagReplacements, urlOverrides],
  );

  const completedTagGroups = detectedGroups.filter((group) =>
    tagReplacements[group.key]?.trim(),
  ).length;
  const completedUrlOverrides = uniqueDetectedLinks.filter((link) =>
    urlOverrides[link.originalUrl]?.trim(),
  ).length;
  const hasAnyReplacement = completedTagGroups + completedUrlOverrides > 0;
  const personalizedLinkCount = uniqueDetectedLinks.filter(
    (link) =>
      Boolean(urlOverrides[link.originalUrl]?.trim()) ||
      link.parameters.some((parameter) =>
        tagReplacements[parameter.replacementKey]?.trim(),
      ),
  ).length;
  const selectedExport =
    history.find((record) => record.id === selectedExportId) ?? history[0];

  useEffect(() => {
    if (!currentUser || hasRequestedArticles.current) return;

    hasRequestedArticles.current = true;
    setArticleLoadError('');

    dispatch(
      fetchArticles({
        query: '/export-studio/source-articles?page=0&limit=50',
      }),
    )
      .unwrap()
      .catch((error) => {
        console.error('Failed to load export studio articles', error);
        setArticleLoadError(
          'Could not load saved articles. The sample articles below are available as a fallback.',
        );
      })
      .finally(() => {
        setHasAttemptedArticleLoad(true);
      });
  }, [currentUser, dispatch]);

  useEffect(() => {
    if (articlesForStudio.length === 0) return;

    if (
      !articlesForStudio.some((article) => article.id === selectedArticleId)
    ) {
      setSelectedArticleId(articlesForStudio[0].id);
    }
  }, [articlesForStudio, selectedArticleId]);

  useEffect(() => {
    setTagReplacements({});
    setUrlOverrides({});
    setSuccessMessage('');
    setErrorMessage('');
  }, [selectedArticleId]);

  useEffect(() => {
    if (typeof window === 'undefined') return;

    const savedHistory = window.localStorage.getItem(historyStorageKey);

    if (savedHistory) {
      try {
        const parsedHistory = JSON.parse(savedHistory) as ExportRecord[];
        setHistory(parsedHistory);
        setSelectedExportId(parsedHistory[0]?.id ?? null);
      } catch (error) {
        console.error('Failed to parse export history', error);
      }
    }
  }, []);

  useEffect(() => {
    if (typeof window === 'undefined') return;

    window.localStorage.setItem(historyStorageKey, JSON.stringify(history));
  }, [history]);

  const handleArticleChange = (event: React.ChangeEvent<HTMLSelectElement>) => {
    setSelectedArticleId(event.target.value);
    setTagReplacements({});
    setUrlOverrides({});
    setSuccessMessage('');
    setErrorMessage('');
  };

  const handleTagReplacementChange = (key: string, value: string) => {
    setTagReplacements((current) => ({ ...current, [key]: value }));
    setSuccessMessage('');
    setErrorMessage('');
  };

  const handleUrlOverrideChange = (url: string, value: string) => {
    setUrlOverrides((current) => ({ ...current, [url]: value }));
    setSuccessMessage('');
    setErrorMessage('');
  };

  const buildExportContent = () => {
    if (format === 'wordpress')
      return buildWordPressXml(selectedArticle, customizedHtml);
    if (format === 'markdown') return buildMarkdown(customizedHtml);
    return customizedHtml;
  };

  const handleExport = () => {
    if (!hasAnyReplacement) {
      setErrorMessage(
        'Add at least one buyer affiliate tag or full URL override before exporting.',
      );
      return;
    }

    const fileName = `${slugify(selectedArticle.title)}-${Date.now()}.${getExtension(format)}`;
    const content = buildExportContent();
    createDownload(fileName, content, format);

    const record: ExportRecord = {
      id: `${Date.now()}`,
      articleTitle: selectedArticle.title,
      format,
      createdAt: new Date().toLocaleString(),
      replacements: personalizedLinkCount,
      fileName,
      preview: stripTags(customizedHtml).slice(0, 170),
    };

    setHistory((current) => [record, ...current].slice(0, 8));
    setSelectedExportId(record.id);
    setSuccessMessage(`${formatLabels[format]} export created and downloaded.`);
    setErrorMessage('');
  };

  return (
    <>
      <Head>
        <title>{getPageTitle('Article Export Studio')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={mdiFileSwapOutline}
          title='Article Export Studio'
          main
        >
          <BaseButton
            href='/articles/articles-list'
            label='Manage articles'
            color='whiteDark'
            roundedFull
          />
        </SectionTitleLineWithButton>

        <div className='mb-6 overflow-hidden rounded-[2rem] bg-[#12332F] p-6 text-white shadow-xl shadow-emerald-950/10'>
          <div className='grid gap-6 lg:grid-cols-[1.3fr_0.7fr] lg:items-end'>
            <div>
              <p className='text-sm font-black uppercase tracking-[0.24em] text-[#B7F8DA]'>
                Buyer workflow
              </p>
              <h2 className='mt-3 text-4xl font-black tracking-tight'>
                Detect affiliate tags, personalize once, and export a ready
                article.
              </h2>
              <p className='mt-3 max-w-3xl text-white/75'>
                Choose a licensed article and the system automatically finds
                common affiliate parameters like Amazon
                <code className='mx-1 rounded bg-white/10 px-1.5 py-0.5 text-[#B7F8DA]'>
                  tag
                </code>
                , ShareASale
                <code className='mx-1 rounded bg-white/10 px-1.5 py-0.5 text-[#B7F8DA]'>
                  u
                </code>
                , and generic
                <code className='mx-1 rounded bg-white/10 px-1.5 py-0.5 text-[#B7F8DA]'>
                  aff
                </code>{' '}
                IDs.
              </p>
            </div>
            <div className='grid grid-cols-3 gap-3 text-center'>
              {[
                [articlesForStudio.length, 'articles'],
                [detectedGroups.length, 'tags found'],
                [personalizedLinkCount, 'links ready'],
              ].map(([value, label]) => (
                <div key={label} className='rounded-3xl bg-white/10 p-4'>
                  <div className='text-3xl font-black text-[#B7F8DA]'>
                    {value}
                  </div>
                  <div className='text-xs font-bold uppercase tracking-wide text-white/60'>
                    {label}
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>

        {(successMessage || errorMessage) && (
          <div
            className={`mb-6 rounded-2xl border px-5 py-4 text-sm font-semibold ${
              successMessage
                ? 'border-emerald-200 bg-emerald-50 text-emerald-800'
                : 'border-red-200 bg-red-50 text-red-800'
            }`}
          >
            {successMessage || errorMessage}
          </div>
        )}

        <div className='grid gap-6 xl:grid-cols-[0.95fr_1.05fr]'>
          <CardBox className='border-0 shadow-sm'>
            <div className='mb-6 flex items-center gap-3'>
              <span className='grid h-12 w-12 place-items-center rounded-2xl bg-blue-50 text-blue-700'>
                <BaseIcon path={mdiLinkVariant} size='24' />
              </span>
              <div>
                <h3 className='text-xl font-black text-slate-900 dark:text-white'>
                  Detected affiliate tags
                </h3>
                <p className='text-sm text-slate-500'>
                  Enter the buyer tag once; matching article links update
                  automatically.
                </p>
              </div>
            </div>

            <div className='space-y-5'>
              <label className='block'>
                <span className='mb-2 block text-sm font-bold text-slate-700 dark:text-slate-200'>
                  Licensed article
                </span>
                <select
                  value={selectedArticleId}
                  onChange={handleArticleChange}
                  className='h-12 w-full rounded-2xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:bg-dark-900 dark:text-white'
                >
                  {articlesForStudio.map((article) => (
                    <option key={article.id} value={article.id}>
                      {article.title}
                    </option>
                  ))}
                </select>
                {articlesLoading && (
                  <p className='mt-2 text-xs font-semibold text-blue-600'>
                    Loading saved articles from the database…
                  </p>
                )}
                {articleLoadError && (
                  <p className='mt-2 text-xs font-semibold text-amber-700'>
                    {articleLoadError}
                  </p>
                )}
                {isUsingFallbackArticles && !articleLoadError && (
                  <p className='mt-2 text-xs font-semibold text-amber-700'>
                    No saved articles were returned yet, so sample articles are
                    shown for testing.
                  </p>
                )}
              </label>

              <div className='grid grid-cols-2 gap-3'>
                <div className='rounded-2xl bg-slate-50 p-4 dark:bg-dark-800'>
                  <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                    Status
                  </p>
                  <p className='mt-1 font-black text-slate-900 dark:text-white'>
                    {selectedArticle.status}
                  </p>
                </div>
                <div className='rounded-2xl bg-slate-50 p-4 dark:bg-dark-800'>
                  <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                    Source
                  </p>
                  <p className='mt-1 font-black text-slate-900 dark:text-white'>
                    {selectedArticle.source}
                  </p>
                </div>
              </div>

              {detectedGroups.length > 0 ? (
                <div className='space-y-4'>
                  <div className='rounded-3xl border border-emerald-100 bg-emerald-50 p-4 text-sm text-emerald-900'>
                    <strong>
                      {detectedGroups.length} affiliate tag group
                      {detectedGroups.length === 1 ? '' : 's'} detected.
                    </strong>{' '}
                    Values entered here replace the publisher tag while
                    preserving the product URL.
                  </div>

                  {detectedGroups.map((group) => (
                    <label
                      key={group.key}
                      className='block rounded-3xl border border-slate-100 bg-white p-4 shadow-sm dark:border-dark-700 dark:bg-dark-900'
                    >
                      <div className='mb-4 flex flex-wrap items-center gap-2'>
                        <span className='rounded-full bg-emerald-100 px-3 py-1 text-xs font-black uppercase tracking-wide text-emerald-800'>
                          {group.network}
                        </span>
                        <span className='rounded-full bg-slate-100 px-3 py-1 text-xs font-bold uppercase tracking-wide text-slate-600 dark:bg-dark-800 dark:text-slate-300'>
                          {group.linkCount} link
                          {group.linkCount === 1 ? '' : 's'}
                        </span>
                      </div>

                      <div className='mb-4 grid gap-3 md:grid-cols-3'>
                        <div>
                          <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                            Domain
                          </p>
                          <p className='mt-1 break-all text-sm font-black text-slate-900 dark:text-white'>
                            {group.domain}
                          </p>
                        </div>
                        <div>
                          <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                            Parameter
                          </p>
                          <code className='mt-1 block rounded-xl bg-slate-950 px-3 py-2 text-xs text-[#B7F8DA]'>
                            ?{group.parameter}=
                          </code>
                        </div>
                        <div>
                          <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                            Publisher tag
                          </p>
                          <code className='mt-1 block break-all rounded-xl bg-slate-950 px-3 py-2 text-xs text-[#B7F8DA]'>
                            {group.currentValue}
                          </code>
                        </div>
                      </div>

                      <span className='mb-2 block text-sm font-bold text-slate-700 dark:text-slate-200'>
                        Buyer {group.parameter} value
                      </span>
                      <input
                        value={tagReplacements[group.key] ?? ''}
                        onChange={(event) =>
                          handleTagReplacementChange(
                            group.key,
                            event.target.value,
                          )
                        }
                        placeholder={getTagPlaceholder(group)}
                        className='h-12 w-full rounded-2xl border border-slate-200 bg-white px-4 text-sm text-slate-800 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:bg-dark-800 dark:text-white'
                      />
                    </label>
                  ))}
                </div>
              ) : (
                <div className='rounded-3xl border border-dashed border-slate-200 p-6 text-center text-sm text-slate-500'>
                  No simple affiliate tag parameters were found in this article.
                  Use the full URL override section below for redirect links or
                  unusual networks.
                </div>
              )}

              <details className='rounded-3xl border border-slate-100 bg-slate-50 p-4 dark:border-dark-700 dark:bg-dark-800'>
                <summary className='cursor-pointer text-sm font-black text-slate-800 dark:text-white'>
                  Advanced fallback: replace a full affiliate URL
                </summary>
                <div className='mt-4 space-y-4'>
                  {uniqueDetectedLinks.length === 0 ? (
                    <p className='rounded-2xl border border-dashed border-slate-200 bg-white p-4 text-sm text-slate-500 dark:border-dark-700 dark:bg-dark-900'>
                      No links were found in this article content.
                    </p>
                  ) : (
                    uniqueDetectedLinks.map((link, index) => (
                      <label
                        key={link.originalUrl}
                        className='block rounded-3xl border border-slate-100 bg-white p-4 shadow-sm dark:border-dark-700 dark:bg-dark-900'
                      >
                        <span className='text-xs font-black uppercase tracking-wide text-slate-500'>
                          Link {index + 1} • {link.network} •{' '}
                          {link.linkText || link.domain}
                        </span>
                        <code className='mt-2 block break-all rounded-2xl bg-slate-950 px-3 py-2 text-xs text-[#B7F8DA]'>
                          {link.originalUrl}
                        </code>
                        <span className='mb-2 mt-4 block text-sm font-bold text-slate-700 dark:text-slate-200'>
                          Replacement URL
                        </span>
                        <input
                          value={urlOverrides[link.originalUrl] ?? ''}
                          onChange={(event) =>
                            handleUrlOverrideChange(
                              link.originalUrl,
                              event.target.value,
                            )
                          }
                          placeholder='https://your-affiliate-link.example/product?tag=buyer-id'
                          className='h-12 w-full rounded-2xl border border-slate-200 bg-white px-4 text-sm text-slate-800 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:bg-dark-800 dark:text-white'
                        />
                      </label>
                    ))
                  )}
                </div>
              </details>

              <div className='rounded-3xl border border-amber-100 bg-amber-50 p-4 text-sm text-amber-900'>
                <strong>Validation:</strong> at least one buyer tag or full URL
                override is required. Empty fields keep the original publisher
                link.
              </div>
            </div>
          </CardBox>

          <CardBox className='border-0 shadow-sm'>
            <div className='mb-6 flex flex-col justify-between gap-4 sm:flex-row sm:items-center'>
              <div className='flex items-center gap-3'>
                <span className='grid h-12 w-12 place-items-center rounded-2xl bg-emerald-50 text-emerald-700'>
                  <BaseIcon path={mdiFileExportOutline} size='24' />
                </span>
                <div>
                  <h3 className='text-xl font-black text-slate-900 dark:text-white'>
                    Preview & download
                  </h3>
                  <p className='text-sm text-slate-500'>
                    Export a draft-ready file for WordPress or manual
                    publishing.
                  </p>
                </div>
              </div>
              <select
                value={format}
                onChange={(event) =>
                  setFormat(event.target.value as ExportFormat)
                }
                className='h-11 rounded-2xl border border-slate-200 bg-white px-4 text-sm font-bold text-slate-800 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-200 dark:bg-dark-900 dark:text-white'
              >
                <option value='wordpress'>WordPress WXR/XML</option>
                <option value='html'>HTML</option>
                <option value='markdown'>Markdown</option>
              </select>
            </div>

            <div className='mb-5 max-h-[31rem] overflow-auto rounded-3xl border border-slate-100 bg-slate-50 p-5 dark:border-dark-700 dark:bg-dark-800'>
              <div
                className='prose max-w-none prose-slate dark:prose-invert'
                dangerouslySetInnerHTML={{ __html: customizedHtml }}
              />
            </div>

            <div className='flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between'>
              <div className='flex items-center gap-2 text-sm font-semibold text-slate-600 dark:text-slate-300'>
                <BaseIcon path={mdiCheckCircleOutline} size='18' />
                {personalizedLinkCount}/{uniqueDetectedLinks.length} links
                personalized
              </div>
              <BaseButton
                label={`Download ${formatLabels[format]}`}
                icon={mdiDownloadBoxOutline}
                color='success'
                roundedFull
                onClick={handleExport}
              />
            </div>
          </CardBox>
        </div>

        <div className='mt-6 grid gap-6 xl:grid-cols-[0.8fr_1.2fr]'>
          <CardBox className='border-0 shadow-sm'>
            <div className='mb-5 flex items-center gap-3'>
              <span className='grid h-11 w-11 place-items-center rounded-2xl bg-slate-100 text-slate-700'>
                <BaseIcon path={mdiHistory} size='22' />
              </span>
              <div>
                <h3 className='text-lg font-black text-slate-900 dark:text-white'>
                  Export history
                </h3>
                <p className='text-sm text-slate-500'>
                  Saved locally for this first iteration.
                </p>
              </div>
            </div>

            {history.length === 0 ? (
              <div className='rounded-3xl border border-dashed border-slate-200 p-6 text-center text-sm text-slate-500'>
                No exports yet. Add a buyer tag or replacement URL and download
                a file to see confirmation history here.
              </div>
            ) : (
              <div className='space-y-3'>
                {history.map((record) => (
                  <button
                    key={record.id}
                    type='button'
                    onClick={() => setSelectedExportId(record.id)}
                    className={`w-full rounded-3xl border p-4 text-left transition focus:outline-none focus:ring-2 focus:ring-blue-200 ${
                      selectedExport?.id === record.id
                        ? 'border-blue-300 bg-blue-50 dark:bg-blue-950/30'
                        : 'border-slate-100 bg-white hover:border-slate-200 dark:border-dark-700 dark:bg-dark-900'
                    }`}
                  >
                    <p className='font-black text-slate-900 dark:text-white'>
                      {record.fileName}
                    </p>
                    <p className='mt-1 text-xs font-semibold uppercase tracking-wide text-slate-500'>
                      {formatLabels[record.format]} • {record.createdAt}
                    </p>
                  </button>
                ))}
              </div>
            )}
          </CardBox>

          <CardBox className='border-0 shadow-sm'>
            <div className='mb-5 flex items-center gap-3'>
              <span className='grid h-11 w-11 place-items-center rounded-2xl bg-purple-50 text-purple-700'>
                <BaseIcon path={mdiFileDocumentOutline} size='22' />
              </span>
              <div>
                <h3 className='text-lg font-black text-slate-900 dark:text-white'>
                  Export detail
                </h3>
                <p className='text-sm text-slate-500'>
                  A lightweight confirmation record for the buyer.
                </p>
              </div>
            </div>

            {selectedExport ? (
              <div className='rounded-3xl bg-slate-50 p-5 dark:bg-dark-800'>
                <div className='grid gap-4 md:grid-cols-2'>
                  <div>
                    <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                      Article
                    </p>
                    <p className='mt-1 font-black text-slate-900 dark:text-white'>
                      {selectedExport.articleTitle}
                    </p>
                  </div>
                  <div>
                    <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                      Format
                    </p>
                    <p className='mt-1 font-black text-slate-900 dark:text-white'>
                      {formatLabels[selectedExport.format]}
                    </p>
                  </div>
                  <div>
                    <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                      Replacements
                    </p>
                    <p className='mt-1 font-black text-slate-900 dark:text-white'>
                      {selectedExport.replacements}
                    </p>
                  </div>
                  <div>
                    <p className='text-xs font-bold uppercase tracking-wide text-slate-500'>
                      Created
                    </p>
                    <p className='mt-1 font-black text-slate-900 dark:text-white'>
                      {selectedExport.createdAt}
                    </p>
                  </div>
                </div>
                <div className='mt-5 rounded-2xl bg-white p-4 text-sm leading-6 text-slate-600 dark:bg-dark-900 dark:text-slate-300'>
                  {selectedExport.preview}...
                </div>
              </div>
            ) : (
              <div className='rounded-3xl border border-dashed border-slate-200 p-6 text-center text-sm text-slate-500'>
                Select an export from history, or create the first download to
                generate a detail record.
              </div>
            )}
          </CardBox>
        </div>
      </SectionMain>
    </>
  );
};

ExportStudio.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};

export default ExportStudio;
