/**
 * Content Analysis Panel - Optimized for Narrow Sidebar
 * Vertical stacking, compact design
 */

import { debounce } from 'lodash';
import { analyzeFocusKeyword, analyzeAllKeywords } from '../../shared/focusKeywordAnalysis';

const PRORANK_EDITOR_META_SYNC_EVENT = 'prorank:editor-meta-sync';

const DEFAULT_CONTENT_ANALYSIS_SETTINGS = {
  enabled: true,
  autoAnalyze: true,
  focusKeywordEnabled: true,
  seoScoreEnabled: true,
  readabilityEnabled: true,
  enable_realtime: true,
  enable_ai_insights: false,
  min_content_length: 300,
  target_readability_score: 60,
  auto_analyze_delay: 2000,
  show_keyword_density: false,
  show_entity_detection: false,
  show_intent_classification: false,
};

const cancelDebounced = (fn) => {
  if (fn && typeof fn.cancel === 'function') {
    fn.cancel();
  }
};

const keywordSignature = (keywords) => (
  Array.isArray(keywords)
    ? keywords.map((kw) => `${kw?.keyword || ''}:${kw?.primary ? '1' : '0'}`).join('|')
    : ''
);

const ContentAnalysisPanel = ({ postId }) => {
  const { useState, useEffect, useCallback, useMemo, useRef } = window.wp.element;
  const { __ = (text) => text } = window.wp?.i18n || {};
  const apiFetch = window.wp.apiFetch;
  const { useSelect } = window.wp.data;
  const { Spinner } = window.wp.components;

  const [readabilityScore, setReadabilityScore] = useState(null);
  const [readabilityLevel, setReadabilityLevel] = useState(null);
  const [readabilityGrade, setReadabilityGrade] = useState(null);
  const [readabilityStats, setReadabilityStats] = useState(null);
  const [inclusiveLanguage, setInclusiveLanguage] = useState(null);
  const [prominentWords, setProminentWords] = useState(null);
  const [isLoadingReadability, setIsLoadingReadability] = useState(false);
  const [isAnalyzing, setIsAnalyzing] = useState(false);
  const [analysis, setAnalysis] = useState(null);
  const [searchIntent, setSearchIntent] = useState(null);
  const [focusKeywords, setFocusKeywords] = useState([]);
  const [focusKeywordsLimit, setFocusKeywordsLimit] = useState(3);
  const [newKeywordInput, setNewKeywordInput] = useState('');
  const [seoTitleMeta, setSeoTitleMeta] = useState('');
  const [seoDescriptionMeta, setSeoDescriptionMeta] = useState('');
  const [canonicalUrlMeta, setCanonicalUrlMeta] = useState('');
  const [seoScore, setSeoScore] = useState(0);
  const [analysisSettings] = useState(() => {
    const merged = {
      ...DEFAULT_CONTENT_ANALYSIS_SETTINGS,
      ...(window?.proRankSidebar?.contentAnalysis || {}),
    };

    // Keep compatibility keys coherent with canonical runtime keys.
    merged.enabled = Boolean(merged.enable_realtime);
    merged.autoAnalyze = Boolean(merged.enable_realtime);
    merged.focusKeywordEnabled = Boolean(merged.show_keyword_density);
    if (typeof merged.seoScoreEnabled !== 'boolean') {
      merged.seoScoreEnabled = true;
    }
    if (typeof merged.readabilityEnabled !== 'boolean') {
      merged.readabilityEnabled = true;
    }

    // Free build: AI insight widgets are not shown in the editor side panel.
    merged.enable_ai_insights = false;
    merged.show_keyword_density = false;
    merged.show_entity_detection = false;
    merged.show_intent_classification = false;
    merged.focusKeywordEnabled = false;

    return merged;
  });
  const hasLoadedKeyword = useRef(false);
  const lastAutoAnalyzeSignature = useRef('');

  const { content, title } = useSelect((select) => {
    const editor = select('core/editor');
    return {
      content: editor.getEditedPostContent() || '',
      title: editor.getEditedPostAttribute('title') || '',
    };
  }, []);

  const wordCount = useMemo(
    () => (content ? content.split(/\s+/).filter((w) => w.length > 0).length : 0),
    [content]
  );
  const minContentLength = Math.max(100, parseInt(analysisSettings.min_content_length, 10) || 300);
  const hasEnoughContent = wordCount >= minContentLength;
  const remainingWords = Math.max(0, minContentLength - wordCount);
  const targetReadability = Math.max(30, parseInt(analysisSettings.target_readability_score, 10) || 60);
  const autoAnalyzeDelay = Math.max(500, Math.min(5000, parseInt(analysisSettings.auto_analyze_delay, 10) || 2000));
  const primaryKeyword = useMemo(() => {
    const primary = focusKeywords.find(kw => kw.primary);
    return primary ? primary.keyword : (focusKeywords[0]?.keyword || '');
  }, [focusKeywords]);

  const analysisContext = useMemo(() => ({
    title,
    seoTitle: seoTitleMeta,
    description: seoDescriptionMeta,
    url: canonicalUrlMeta,
    content,
  }), [title, seoTitleMeta, seoDescriptionMeta, canonicalUrlMeta, content]);

  const multiKeywordAnalysis = useMemo(
    () => analyzeAllKeywords(focusKeywords, analysisContext),
    [focusKeywords, analysisContext]
  );

  // Primary keyword analysis — used for the detailed 7-check card.
  const focusKeywordAnalysis = multiKeywordAnalysis.primary || analyzeFocusKeyword({ keyword: '', ...analysisContext });
  const focusKeywordChecks = useMemo(
    () => [
      {
        key: 'title',
        label: __('Keyword in SEO title', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.title,
      },
      {
        key: 'description',
        label: __('Keyword in meta description', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.description,
      },
      {
        key: 'url',
        label: __('Keyword in URL', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.url,
      },
      {
        key: 'firstParagraph',
        label: __('Keyword in first paragraph', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.firstParagraph,
      },
      {
        key: 'headings',
        label: __('Keyword in headings', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.headings,
      },
      {
        key: 'density',
        label: __('Keyword density looks natural', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.density,
      },
      {
        key: 'imageAlt',
        label: __('Keyword in image alt text', 'prorank-seo'),
        data: focusKeywordAnalysis.checks.imageAlt,
      },
    ],
    [focusKeywordAnalysis.checks, __]
  );

  const calculateSeoScore = useCallback(() => {
    let score = 0;
    let weight = 0;

    if (readabilityScore !== null) {
      const readabilityNormalized = Math.min(100, Math.max(0, (readabilityScore / targetReadability) * 100));
      score += readabilityNormalized * 0.3;
      weight += 0.3;
    }
    if (analysis?.structure_score) {
      score += analysis.structure_score.score * 0.15;
      weight += 0.15;
    }

    const keywordScore = multiKeywordAnalysis.aggregate;
    score += keywordScore * 0.35;
    weight += 0.35;

    score += (
      wordCount >= Math.max(minContentLength, 1000)
        ? 100
        : wordCount >= Math.max(minContentLength, 600)
          ? 75
          : wordCount >= minContentLength
            ? 50
            : 0
    ) * 0.2;
    weight += 0.2;

    setSeoScore(weight > 0 ? Math.round(score / weight) : 0);
  }, [readabilityScore, analysis, targetReadability, wordCount, minContentLength, multiKeywordAnalysis.aggregate]);

  useEffect(() => { calculateSeoScore(); }, [calculateSeoScore]);

  const fetchReadabilityScore = useCallback(async (pid) => {
    if (!pid) return;
    setIsLoadingReadability(true);
    try {
      const res = await apiFetch({ path: `/prorank-seo/v1/readability-score/${pid}`, method: 'GET' });
      if (res?.data) {
        setReadabilityScore(res.data.score);
        setReadabilityLevel(res.data.level);
        setReadabilityGrade(res.data.grade);
        setReadabilityStats(res.data.stats);
        setInclusiveLanguage(res.data.inclusive_language || null);
        setProminentWords(res.data.prominent_words || null);
      }
    } catch (e) { console.error('Readability error:', e); }
    finally { setIsLoadingReadability(false); }
  }, []);

  const debouncedFetch = useMemo(() => debounce((id) => fetchReadabilityScore(id), autoAnalyzeDelay), [fetchReadabilityScore, autoAnalyzeDelay]);
  useEffect(() => {
    if (!analysisSettings.enable_realtime || !analysisSettings.readabilityEnabled) {
      return () => cancelDebounced(debouncedFetch);
    }
    if (postId && content && wordCount >= minContentLength) {
      debouncedFetch(postId);
    }
    return () => cancelDebounced(debouncedFetch);
  }, [analysisSettings.enable_realtime, analysisSettings.readabilityEnabled, postId, content, wordCount, minContentLength, debouncedFetch]);

  const saveFocusKeywords = useCallback(
    async (keywords) => {
      if (!postId) return;
      try {
        const response = await apiFetch({
          path: `/prorank-seo/v1/meta/${postId}`,
          method: 'POST',
          data: { focus_keywords: keywords },
        });
        // Reconcile: apply server-normalized keywords back to local state.
        if (Array.isArray(response?.data?.focus_keywords)) {
          setFocusKeywords((currentKeywords) => (
            keywordSignature(currentKeywords) === keywordSignature(response.data.focus_keywords)
              ? currentKeywords
              : response.data.focus_keywords
          ));
        }
      } catch (e) {
        console.error('Focus keywords save failed:', e);
      }
    },
    [postId]
  );

  const debouncedSaveFocusKeywords = useMemo(
    () => debounce((keywords) => saveFocusKeywords(keywords), 600),
    [saveFocusKeywords]
  );

  useEffect(() => () => cancelDebounced(debouncedSaveFocusKeywords), [debouncedSaveFocusKeywords]);

  const addKeyword = useCallback(
    (keyword) => {
      const trimmed = (typeof keyword === 'string' ? keyword : '').trim();
      if (!trimmed || focusKeywords.length >= focusKeywordsLimit) return;
      const lower = trimmed.toLowerCase();
      if (focusKeywords.some(kw => kw.keyword.toLowerCase() === lower)) return;
      const isPrimary = focusKeywords.length === 0;
      const next = [...focusKeywords, { keyword: trimmed, primary: isPrimary }];
      setFocusKeywords(next);
      setNewKeywordInput('');
      debouncedSaveFocusKeywords(next);
    },
    [focusKeywords, focusKeywordsLimit, debouncedSaveFocusKeywords]
  );

  const removeKeyword = useCallback(
    (index) => {
      const next = [...focusKeywords];
      const wasPrimary = next[index].primary;
      next.splice(index, 1);
      if (wasPrimary && next.length > 0) {
        next[0].primary = true;
      }
      setFocusKeywords(next);
      debouncedSaveFocusKeywords(next);
    },
    [focusKeywords, debouncedSaveFocusKeywords]
  );

  const setPrimaryKeyword = useCallback(
    (index) => {
      const next = focusKeywords.map((kw, i) => ({ ...kw, primary: i === index }));
      setFocusKeywords(next);
      debouncedSaveFocusKeywords(next);
    },
    [focusKeywords, debouncedSaveFocusKeywords]
  );

  const moveKeyword = useCallback(
    (fromIndex, direction) => {
      const toIndex = fromIndex + direction;
      if (toIndex < 0 || toIndex >= focusKeywords.length) return;
      const next = [...focusKeywords];
      const [moved] = next.splice(fromIndex, 1);
      next.splice(toIndex, 0, moved);
      setFocusKeywords(next);
      debouncedSaveFocusKeywords(next);
    },
    [focusKeywords, debouncedSaveFocusKeywords]
  );

  useEffect(() => {
    if (!postId || hasLoadedKeyword.current) return;
    apiFetch({ path: `/prorank-seo/v1/meta/${postId}`, method: 'GET' })
      .then((response) => {
        if (response?.data) {
          if (Array.isArray(response.data.focus_keywords) && response.data.focus_keywords.length > 0) {
            setFocusKeywords(response.data.focus_keywords);
          } else if (response.data.focus_keyword) {
            setFocusKeywords([{ keyword: response.data.focus_keyword, primary: true }]);
          }
          if (response.data.focus_keywords_limit) {
            setFocusKeywordsLimit(response.data.focus_keywords_limit);
          }
          setSeoTitleMeta(response.data.seo_title || '');
          setSeoDescriptionMeta(response.data.seo_description || '');
          setCanonicalUrlMeta(response.data.canonical_url || response.data.defaults?.url || '');
        }
      })
      .catch((e) => console.error('Focus keyword load failed:', e))
      .finally(() => { hasLoadedKeyword.current = true; });
  }, [postId, apiFetch]);

  useEffect(() => {
    const handleMetaSync = (event) => {
      const detail = event?.detail || {};
      if (detail.postId !== postId) {
        return;
      }

      if (Object.prototype.hasOwnProperty.call(detail, 'seoTitle')) {
        setSeoTitleMeta(detail.seoTitle || '');
      }
      if (Object.prototype.hasOwnProperty.call(detail, 'seoDescription')) {
        setSeoDescriptionMeta(detail.seoDescription || '');
      }
      if (Object.prototype.hasOwnProperty.call(detail, 'canonicalUrl')) {
        setCanonicalUrlMeta(detail.canonicalUrl || '');
      }
      if (Array.isArray(detail.focusKeywords)) {
        setFocusKeywords(detail.focusKeywords);
      }
    };

    window.addEventListener(PRORANK_EDITOR_META_SYNC_EVENT, handleMetaSync);
    return () => window.removeEventListener(PRORANK_EDITOR_META_SYNC_EVENT, handleMetaSync);
  }, [postId]);

  const analyzeContent = useCallback(async (options = {}) => {
    if (!content || !analysisSettings.enable_ai_insights || wordCount < minContentLength) return;
    const { persistKeywords = true } = options || {};
    setIsAnalyzing(true);
    try {
      if (persistKeywords) {
        await saveFocusKeywords(focusKeywords);
      }
      const res = await apiFetch({ path: '/prorank-seo/v1/content/analyze', method: 'POST', data: { content, title, focus_keyword: primaryKeyword } });
      if (res?.data) {
        setAnalysis(res.data);
      }
      if (analysisSettings.show_intent_classification) {
        try {
          const intentRes = await apiFetch({ path: '/prorank-seo/v1/content/intent', method: 'POST', data: { title, content } });
          if (intentRes?.data) {
            setSearchIntent(intentRes.data);
          }
        } catch (intentError) {
          setSearchIntent(null);
          console.error('Intent analysis error:', intentError);
        }
      }
    } catch (e) { console.error('Analysis error:', e); }
    finally { setIsAnalyzing(false); }
  }, [content, title, primaryKeyword, focusKeywords, analysisSettings.enable_ai_insights, analysisSettings.show_intent_classification, wordCount, minContentLength, saveFocusKeywords, apiFetch]);

  const debouncedAnalyze = useMemo(() => debounce((signature) => {
    if (lastAutoAnalyzeSignature.current === signature) {
      return;
    }
    lastAutoAnalyzeSignature.current = signature;
    analyzeContent({ persistKeywords: false });
  }, autoAnalyzeDelay), [analyzeContent, autoAnalyzeDelay]);
  useEffect(() => {
    if (
      analysisSettings.enable_realtime &&
      analysisSettings.enable_ai_insights &&
      content &&
      primaryKeyword &&
      wordCount >= minContentLength
    ) {
      debouncedAnalyze(`${postId || ''}|${primaryKeyword}|${title}|${content}`);
    }
    return () => cancelDebounced(debouncedAnalyze);
  }, [analysisSettings.enable_realtime, analysisSettings.enable_ai_insights, content, primaryKeyword, wordCount, minContentLength, postId, title, debouncedAnalyze]);

  const getColor = (s) => s >= 70 ? '#3b82f6' : s >= 40 ? '#f59e0b' : '#ef4444';
  const getContentStatus = (s) => {
    if (!hasEnoughContent) return __('Build Out', 'prorank-seo');
    return s >= 80
      ? __('Strong', 'prorank-seo')
      : s >= 60
        ? __('Solid', 'prorank-seo')
        : s >= 40
          ? __('Developing', 'prorank-seo')
          : __('Needs Work', 'prorank-seo');
  };
  const getStatusDotColor = (s) =>
    s >= 80 ? '#22C55E' : s >= 60 ? '#B64206' : s >= 40 ? '#F59E0B' : '#EF4444';
  const getScoreVariant = (s) => (s >= 75 ? '' : s >= 50 ? ' warn' : ' bad');
  const getStatusHint = (s, t) => {
    if (s >= 80) return t('ready to publish', 'prorank-seo');
    if (s >= 60) return t('on track — fine-tune to ship', 'prorank-seo');
    if (s >= 40) return t('keep developing', 'prorank-seo');
    return t('needs work before publishing', 'prorank-seo');
  };
  const displayedSeoScore = hasEnoughContent ? seoScore : '—';
  const displayedReadabilityScore = hasEnoughContent && readabilityScore !== null ? Math.round(readabilityScore) : '—';
  const readTime = readabilityStats?.estimated_reading_time || Math.ceil(wordCount / 200);

  return (
    <div className="prs">
      <style>{`
        .prs { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; font-size: 13px; color: #374151; }

        /* Editorial score block — paper-toned, brand palette */
        .prs-score { padding: 22px 16px 18px; background: #fff; border-bottom: 1px solid #E7EAF0; }
        .prs-eyebrow { display: flex; align-items: center; gap: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 10px; letter-spacing: 0.18em; text-transform: uppercase; color: #5B6475; margin: 0 0 16px 0; }
        .prs-eyebrow::before { content: ''; width: 18px; height: 2px; background: #B64206; flex-shrink: 0; }
        .prs-headline { display: flex; align-items: baseline; gap: 6px; margin: 0; }
        .prs-headline-num { font-family: ui-sans-serif, system-ui, -apple-system, 'Segoe UI', sans-serif; font-size: 56px; font-weight: 700; line-height: 0.95; letter-spacing: -0.03em; color: #0B0F1A; }
        .prs-headline-suffix { font-size: 17px; font-weight: 400; color: #5B6475; letter-spacing: -0.01em; }
        .prs-status { display: flex; align-items: center; gap: 9px; margin: 14px 0 0 0; font-family: 'Instrument Serif', 'Iowan Old Style', Georgia, serif; font-style: italic; font-size: 19px; color: #0B0F1A; line-height: 1.1; }
        .prs-status-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
        .prs-status-hint { font-family: ui-sans-serif, system-ui, sans-serif; font-style: normal; font-size: 11px; color: #5B6475; margin: 5px 0 0 16px; line-height: 1.4; }
        .prs-divider { height: 1px; background: #E7EAF0; margin: 18px 0 14px 0; }

        /* Stats row — hairline divided */
        .prs-stats { display: flex; align-items: stretch; }
        .prs-stat { flex: 1; text-align: center; padding: 0 4px; border-right: 1px solid #E7EAF0; }
        .prs-stat:last-child { border-right: none; }
        .prs-stat-name { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 9px; letter-spacing: 0.16em; text-transform: uppercase; color: #5B6475; margin-bottom: 4px; }
        .prs-stat-val { font-family: ui-sans-serif, system-ui, sans-serif; font-size: 18px; font-weight: 700; color: #0B0F1A; letter-spacing: -0.02em; line-height: 1.1; }
        .prs-stat-suffix { font-size: 12px; font-weight: 400; color: #5B6475; letter-spacing: 0; margin-left: 1px; }
        .prs-stat-val.warn { color: #B64206; }
        .prs-stat-val.bad { color: #B91C1C; }

        /* Section — editorial */
        .prs-sec { padding: 18px 16px; border-bottom: 1px solid #E7EAF0; }
        .prs-sec:last-child { border-bottom: none; }
        .prs-title { display: flex; align-items: center; gap: 10px; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 10px; font-weight: 600; letter-spacing: 0.18em; text-transform: uppercase; color: #5B6475; margin: 0 0 14px 0; }
        .prs-title::before { content: ''; width: 14px; height: 2px; background: #B64206; flex-shrink: 0; }

        /* Form controls */
        .prs-input { width: 100%; padding: 9px 10px; border: 1px solid #E7EAF0; border-radius: 4px; font-size: 13px; box-sizing: border-box; margin-bottom: 10px; background: #fff; transition: border-color 0.15s ease; }
        .prs-input:focus { outline: none; border-color: #B64206; }
        .prs-btn { width: 100%; padding: 11px 14px; background: #FF6A00; color: #fff; border: none; border-radius: 4px; font-size: 13px; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 8px; letter-spacing: 0.005em; transition: background 0.15s ease; }
        .prs-btn:hover:not(:disabled) { background: #E85E00; }
        .prs-btn:disabled { opacity: 0.45; cursor: not-allowed; }

        /* Editorial score row — replaces gradient pill cards */
        .prs-kw-summary, .prs-read { display: flex; align-items: baseline; gap: 12px; padding: 6px 0 12px 0; border-bottom: 1px solid #E7EAF0; margin-top: 0; background: transparent; border-radius: 0; }
        .prs-kw-summary + .prs-kw-summary { padding-top: 12px; }
        .prs-kw-score, .prs-read-badge { width: auto; height: auto; border-radius: 0; background: none !important; color: #0B0F1A; font-family: ui-sans-serif, system-ui, sans-serif; font-size: 36px; font-weight: 700; line-height: 0.95; letter-spacing: -0.025em; flex-shrink: 0; }
        .prs-kw-score.warn, .prs-read-badge.warn { color: #B64206; }
        .prs-kw-score.bad, .prs-read-badge.bad { color: #B91C1C; }
        .prs-kw-copy, .prs-read-info { flex: 1; min-width: 0; }
        .prs-kw-copy strong, .prs-read-level { display: block; font-family: 'Instrument Serif', 'Iowan Old Style', Georgia, serif; font-style: normal; font-weight: 400; font-size: 16px; color: #0B0F1A; line-height: 1.2; }
        .prs-kw-copy span, .prs-read-grade { display: block; font-size: 11px; color: #5B6475; margin-top: 4px; line-height: 1.45; }

        /* Checks — hairline-divided rows */
        .prs-checks { margin-top: 10px; display: flex; flex-direction: column; gap: 0; border-top: 1px solid #E7EAF0; }
        .prs-check { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 9px 0; border-bottom: 1px solid #E7EAF0; border-radius: 0; background: transparent; border-top: none; border-left: none; border-right: none; }
        .prs-check:last-child { border-bottom: none; }
        .prs-check-main { display: flex; align-items: center; gap: 10px; min-width: 0; }
        .prs-check-icon { width: 14px; text-align: center; font-weight: 700; flex-shrink: 0; font-size: 12px; line-height: 1; }
        .prs-check-icon.pass { color: #16A34A; }
        .prs-check-icon.fail { color: #B91C1C; }
        .prs-check-icon.na { color: #94A3B8; }
        .prs-check-label { font-size: 12px; color: #0B0F1A; line-height: 1.35; }
        .prs-check-meta { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 10px; color: #5B6475; white-space: nowrap; flex-shrink: 0; letter-spacing: 0.04em; }

        /* Issues — hairline-divided list */
        .prs-issues { margin-top: 4px; }
        .prs-issue { display: flex; align-items: flex-start; gap: 9px; padding: 8px 0; font-size: 12px; color: #0B0F1A; border-bottom: 1px solid #E7EAF0; line-height: 1.45; }
        .prs-issue:last-child { border-bottom: none; }
        .prs-dot { width: 5px; height: 5px; border-radius: 50%; background: #B64206; margin-top: 7px; flex-shrink: 0; }

        .prs-loading { display: flex; justify-content: center; padding: 16px; }
        .prs-empty { padding: 12px 0; text-align: left; color: #5B6475; font-size: 12px; line-height: 1.45; }
        .prs-note { margin-top: 8px; padding: 10px 12px; text-align: left; color: #0B0F1A; font-size: 12px; line-height: 1.5; background: #FAF7F1; border-left: 2px solid #B64206; border-radius: 0; }
        .prs-score-note { margin-top: 14px; padding: 10px 12px; border-radius: 0; background: #FAF7F1; border-left: 2px solid #B64206; color: #0B0F1A; font-size: 11px; line-height: 1.45; }

        /* Secondary keywords — compact list */
        .prs-secondary { margin-top: 14px; display: flex; flex-direction: column; gap: 0; border-top: 1px solid #E7EAF0; }
        .prs-secondary-label { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 9px; font-weight: 600; color: #5B6475; text-transform: uppercase; letter-spacing: 0.16em; padding: 12px 0 8px 0; }
        .prs-secondary-row { display: flex; align-items: baseline; gap: 10px; padding: 8px 0; border-bottom: 1px solid #E7EAF0; }
        .prs-secondary-row:last-child { border-bottom: none; }
        .prs-secondary-num { font-family: ui-sans-serif, system-ui, sans-serif; font-size: 18px; font-weight: 700; color: #0B0F1A; letter-spacing: -0.02em; flex-shrink: 0; min-width: 26px; line-height: 1; }
        .prs-secondary-num.warn { color: #B64206; }
        .prs-secondary-num.bad { color: #B91C1C; }
        .prs-secondary-name { flex: 1; font-size: 12px; color: #0B0F1A; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-style: italic; font-family: 'Instrument Serif', Georgia, serif; }
        .prs-secondary-meta { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 10px; color: #5B6475; white-space: nowrap; letter-spacing: 0.04em; }
      `}</style>

      {/* Score Section — editorial */}
      {analysisSettings.seoScoreEnabled && (
        <div className="prs-score">
          <div className="prs-eyebrow">{`§ 01 — ${__('content score', 'prorank-seo')}`}</div>

          <div className="prs-headline">
            <span className="prs-headline-num">{displayedSeoScore}</span>
            <span className="prs-headline-suffix">/ 100</span>
          </div>

          <div className="prs-status">
            <span
              className="prs-status-dot"
              style={{ background: hasEnoughContent ? getStatusDotColor(seoScore) : '#CBD5E1' }}
              aria-hidden="true"
            />
            <span>{getContentStatus(seoScore).toLowerCase()}</span>
          </div>
          {hasEnoughContent && (
            <div className="prs-status-hint">{getStatusHint(seoScore, __)}</div>
          )}

          <div className="prs-divider" />

          <div className="prs-stats">
            <div className="prs-stat">
              <div className="prs-stat-name">{__('Read', 'prorank-seo')}</div>
              <div className="prs-stat-val">{readTime}<span className="prs-stat-suffix">m</span></div>
            </div>
            <div className="prs-stat">
              <div className="prs-stat-name">{__('Words', 'prorank-seo')}</div>
              <div className={`prs-stat-val${wordCount < minContentLength ? ' warn' : ''}`}>{wordCount}</div>
            </div>
            <div className="prs-stat">
              <div className="prs-stat-name">{__('Readable', 'prorank-seo')}</div>
              <div
                className={`prs-stat-val${
                  hasEnoughContent && readabilityScore !== null && readabilityScore < Math.max(30, targetReadability - 20)
                    ? ' bad'
                    : hasEnoughContent && readabilityScore !== null && readabilityScore < targetReadability
                      ? ' warn'
                      : ''
                }`}
              >
                {displayedReadabilityScore}
                <span className="prs-stat-suffix">/{targetReadability}</span>
              </div>
            </div>
          </div>

          {!hasEnoughContent && (
            <div className="prs-score-note">
              {`${wordCount} / ${minContentLength} words. Add ${remainingWords} more words to unlock full readability and content scoring.`}
            </div>
          )}
        </div>
      )}

      {/* Focus Keywords - Stacked */}
      <div className="prs-sec">
        <div style={{ display: 'flex', alignItems: 'center', gap: '6px', marginBottom: '8px' }}>
          <h4 className="prs-title" style={{ margin: 0 }}>Focus Keywords</h4>
          <span style={{ fontSize: '10px', color: '#6b7280', padding: '1px 6px', background: '#f3f4f6', borderRadius: '8px' }}>
            {`${focusKeywords.length}/${focusKeywordsLimit}`}
          </span>
        </div>
        <div style={{ display: 'flex', gap: '6px', marginBottom: focusKeywords.length > 0 ? '6px' : '0' }}>
          <input
            type="text"
            className="prs-input"
            style={{ marginBottom: 0 }}
            value={newKeywordInput}
            onChange={(e) => setNewKeywordInput(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter') {
                e.preventDefault();
                addKeyword(newKeywordInput);
              }
            }}
            placeholder={focusKeywords.length >= focusKeywordsLimit ? 'Limit reached' : 'Enter keyword...'}
            disabled={focusKeywords.length >= focusKeywordsLimit}
            aria-label="Add keyword"
          />
          <button
            type="button"
            onClick={() => addKeyword(newKeywordInput)}
            disabled={!newKeywordInput.trim() || focusKeywords.length >= focusKeywordsLimit}
            style={{ padding: '6px 10px', background: '#3b82f6', color: '#fff', border: 'none', borderRadius: '6px', fontSize: '12px', fontWeight: 600, cursor: 'pointer', whiteSpace: 'nowrap', opacity: (!newKeywordInput.trim() || focusKeywords.length >= focusKeywordsLimit) ? 0.5 : 1 }}
          >
            Add
          </button>
        </div>

        {focusKeywords.length > 0 && (
          <div style={{ display: 'flex', flexDirection: 'column', gap: '3px', marginBottom: '6px' }}>
            {focusKeywords.map((kw, index) => (
              <div
                key={index}
                style={{
                  display: 'flex',
                  alignItems: 'center',
                  gap: '4px',
                  padding: '4px 8px',
                  borderRadius: '5px',
                  border: `1px solid ${kw.primary ? '#3b82f6' : '#e5e7eb'}`,
                  background: kw.primary ? '#eff6ff' : '#fff',
                  fontSize: '12px',
                }}
              >
                <button
                  type="button"
                  onClick={() => setPrimaryKeyword(index)}
                  title={kw.primary ? 'Primary keyword' : 'Set as primary'}
                  style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '1px', color: kw.primary ? '#2563eb' : '#9ca3af', fontSize: '14px', lineHeight: 1 }}
                >
                  {kw.primary ? '\u2605' : '\u2606'}
                </button>
                <span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>{kw.keyword}</span>
                {focusKeywords.length > 1 && (
                  <>
                    <button
                      type="button"
                      onClick={() => moveKeyword(index, -1)}
                      disabled={index === 0}
                      title="Move up"
                      style={{ background: 'none', border: 'none', cursor: index === 0 ? 'default' : 'pointer', padding: '1px', color: index === 0 ? '#d1d5db' : '#6b7280', fontSize: '9px', lineHeight: 1 }}
                    >
                      {'\u25B2'}
                    </button>
                    <button
                      type="button"
                      onClick={() => moveKeyword(index, 1)}
                      disabled={index === focusKeywords.length - 1}
                      title="Move down"
                      style={{ background: 'none', border: 'none', cursor: index === focusKeywords.length - 1 ? 'default' : 'pointer', padding: '1px', color: index === focusKeywords.length - 1 ? '#d1d5db' : '#6b7280', fontSize: '9px', lineHeight: 1 }}
                    >
                      {'\u25BC'}
                    </button>
                  </>
                )}
                <button
                  type="button"
                  onClick={() => removeKeyword(index)}
                  title="Remove"
                  style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '1px', color: '#ef4444', fontSize: '11px', lineHeight: 1 }}
                >
                  {'\u2715'}
                </button>
              </div>
            ))}
          </div>
        )}

        {analysisSettings.enable_ai_insights && (
          <button
            className="prs-btn"
            onClick={() => analyzeContent({ persistKeywords: true })}
            disabled={isAnalyzing || !content || !hasEnoughContent}
          >
            {isAnalyzing ? <Spinner /> : hasEnoughContent ? 'Analyze Content' : `Add ${remainingWords} More Words`}
          </button>
        )}

        {!hasEnoughContent && (
          <div className="prs-note">
            {`Basic keyword checks work on short drafts. Add at least ${minContentLength} words to enable full content analysis and readability scoring.`}
          </div>
        )}

        {!primaryKeyword ? (
          <div className="prs-empty" style={{ marginTop: '8px', textAlign: 'left' }}>
            {__('Add a focus keyword to check title, description, URL, headings, paragraph placement, density, and image alt text.', 'prorank-seo')}
          </div>
        ) : (
          <>
            {/* Aggregate score banner (shown when multiple keywords) */}
            {multiKeywordAnalysis.secondary.length > 0 && (
              <div className="prs-kw-summary">
                <div className={`prs-kw-score${getScoreVariant(multiKeywordAnalysis.aggregate)}`}>
                  {multiKeywordAnalysis.aggregate}
                </div>
                <div className="prs-kw-copy">
                  <strong>{__('Overall keyword score', 'prorank-seo')}</strong>
                  <span>
                    {`${focusKeywords.length} ${__('keywords', 'prorank-seo')} · ${__('primary 70% + secondary 30%', 'prorank-seo')}`}
                  </span>
                </div>
              </div>
            )}

            {/* Primary keyword detail */}
            <div className="prs-kw-summary">
              <div className={`prs-kw-score${getScoreVariant(focusKeywordAnalysis.score)}`}>
                {focusKeywordAnalysis.score}
              </div>
              <div className="prs-kw-copy">
                <strong>
                  {multiKeywordAnalysis.secondary.length > 0
                    ? `\u2605 "${focusKeywordAnalysis.keyword}"`
                    : __('Focus keyword coverage', 'prorank-seo')
                  }
                </strong>
                <span>
                  {`${focusKeywordAnalysis.occurrenceCount} ${__('uses', 'prorank-seo')} · ${focusKeywordAnalysis.density.toFixed(2)}% ${__('density', 'prorank-seo')}`}
                </span>
              </div>
            </div>

            <div className="prs-checks">
              {focusKeywordChecks.map((check) => {
                const state = check.data.applicable ? (check.data.passed ? 'pass' : 'fail') : 'na';
                let meta = '';

                if (check.key === 'density' && check.data.applicable) {
                  meta = `${focusKeywordAnalysis.density.toFixed(2)}%`;
                } else if (check.key === 'headings' && check.data.applicable) {
                  meta = `${focusKeywordAnalysis.checks.headings.detail.length} H`;
                } else if (check.key === 'imageAlt' && check.data.applicable) {
                  meta = `${focusKeywordAnalysis.checks.imageAlt.detail.length} alt`;
                }

                return (
                  <div key={check.key} className="prs-check">
                    <div className="prs-check-main">
                      <span className={`prs-check-icon ${state}`}>
                        {state === 'pass' ? '✓' : state === 'fail' ? '!' : '–'}
                      </span>
                      <span className="prs-check-label">{check.label}</span>
                    </div>
                    {meta ? <span className="prs-check-meta">{meta}</span> : null}
                  </div>
                );
              })}
            </div>

            {/* Secondary keyword summaries */}
            {multiKeywordAnalysis.secondary.length > 0 && (
              <div className="prs-secondary">
                <div className="prs-secondary-label">
                  {__('Secondary keywords', 'prorank-seo')}
                </div>
                {multiKeywordAnalysis.secondary.map((result, i) => {
                  const passedCount = Object.values(result.checks).filter(c => c.applicable && c.passed).length;
                  const applicableCount = Object.values(result.checks).filter(c => c.applicable).length;
                  return (
                    <div key={i} className="prs-secondary-row">
                      <span className={`prs-secondary-num${getScoreVariant(result.score)}`}>
                        {result.score}
                      </span>
                      <span className="prs-secondary-name">{`"${result.keyword}"`}</span>
                      <span className="prs-secondary-meta">{`${passedCount}/${applicableCount}`}</span>
                    </div>
                  );
                })}
              </div>
            )}
          </>
        )}
      </div>

      {/* Entities */}
      {analysisSettings.enable_ai_insights && analysisSettings.show_entity_detection && Array.isArray(analysis?.entities) && analysis.entities.length > 0 && (
        <div className="prs-sec">
          <h4 className="prs-title">Entities</h4>
          <div className="prs-issues">
            {analysis.entities.slice(0, 5).map((entity, i) => (
              <div key={i} className="prs-issue">
                <span className="prs-dot"></span>
                <span>{`${entity.value} (${entity.type})`}</span>
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Search Intent */}
      {analysisSettings.enable_ai_insights && analysisSettings.show_intent_classification && searchIntent?.primary_intent && (
        <div className="prs-sec">
          <h4 className="prs-title">Search Intent</h4>
          <div className="prs-read">
            <div className="prs-read-badge">
              {Math.max(0, parseInt(searchIntent.confidence || 0, 10))}<span className="prs-stat-suffix">%</span>
            </div>
            <div className="prs-read-info">
              <div className="prs-read-level">{String(searchIntent.primary_intent || '').replace('_', ' ')}</div>
              <div className="prs-read-grade">Confidence</div>
            </div>
          </div>
        </div>
      )}

      {/* Readability */}
      {analysisSettings.readabilityEnabled && (
        <div className="prs-sec">
          <h4 className="prs-title">Readability</h4>
          {isLoadingReadability ? (
            <div className="prs-loading"><Spinner /></div>
          ) : readabilityScore !== null ? (
            <div className="prs-read">
              <div className={`prs-read-badge${readabilityScore >= targetReadability ? '' : readabilityScore >= Math.max(30, targetReadability - 20) ? ' warn' : ' bad'}`}>
                {Math.round(readabilityScore)}
              </div>
              <div className="prs-read-info">
                <div className="prs-read-level">{readabilityLevel}</div>
                <div className="prs-read-grade">{readabilityGrade}</div>
              </div>
            </div>
          ) : (
            <div className="prs-empty">
              {hasEnoughContent ? 'Add content to analyze' : `${wordCount} / ${minContentLength} words. Readability analysis starts once the draft is longer.`}
            </div>
          )}
        </div>
      )}

      {/* Task 8 — Prominent Words */}
      {prominentWords?.enabled && (
        <div className="prs-sec">
          <h4 className="prs-title">{__('Prominent Words', 'prorank-seo')}</h4>
          {prominentWords.indexed && Array.isArray(prominentWords.terms) && prominentWords.terms.length > 0 ? (
            <>
              <div className="prs-pw-chips" style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
                {prominentWords.terms.slice(0, 20).map((row, idx) => (
                  <span
                    key={`${row.term}-${idx}`}
                    title={`${row.term} · count ${row.count}${row.from_title ? ' · in title' : ''}`}
                    style={{
                      display: 'inline-flex',
                      alignItems: 'center',
                      gap: 4,
                      padding: '3px 8px',
                      borderRadius: 999,
                      background: row.from_title ? '#e5f1ff' : '#f1f5f9',
                      color: '#1e293b',
                      fontSize: 11,
                      lineHeight: 1.6,
                      border: '1px solid ' + (row.from_title ? '#c7e0ff' : '#e2e8f0'),
                    }}
                  >
                    <span>{row.term}</span>
                    <span style={{ color: '#64748b' }}>{row.count}</span>
                  </span>
                ))}
              </div>
              {prominentWords.stale && (
                <div className="prs-empty" style={{ marginTop: 6, fontSize: 11 }}>
                  {__('Index is stale — save the post to refresh.', 'prorank-seo')}
                </div>
              )}
            </>
          ) : (
            <div className="prs-empty">
              {prominentWords.indexed
                ? __('No prominent terms found yet — keep writing.', 'prorank-seo')
                : __('Not indexed yet. Save the post to build the index.', 'prorank-seo')}
            </div>
          )}
        </div>
      )}

      {/* Task 7 — Inclusive Language */}
      {inclusiveLanguage?.enabled && (
        <div className="prs-sec">
          <h4 className="prs-title">{__('Inclusive Language', 'prorank-seo')}</h4>
          {inclusiveLanguage.total_issues === 0 ? (
            <div className="prs-read">
              <div className="prs-read-badge" style={{ background: '#0a7d32', color: '#fff' }}>
                {__('Pass', 'prorank-seo')}
              </div>
              <div className="prs-read-info">
                <div className="prs-read-level">{__('No flagged terms', 'prorank-seo')}</div>
                <div className="prs-read-grade">{__('Curated dictionary', 'prorank-seo')}</div>
              </div>
            </div>
          ) : (
            <>
              <div className="prs-read">
                <div className="prs-read-badge warn">
                  {__('Review', 'prorank-seo')}
                </div>
                <div className="prs-read-info">
                  <div className="prs-read-level">
                    {`${inclusiveLanguage.total_issues} ${
                      inclusiveLanguage.total_issues === 1
                        ? __('flagged term', 'prorank-seo')
                        : __('flagged terms', 'prorank-seo')
                    }`}
                  </div>
                  <div className="prs-read-grade">
                    {[
                      inclusiveLanguage.severity_counts?.high
                        ? `${inclusiveLanguage.severity_counts.high} high`
                        : '',
                      inclusiveLanguage.severity_counts?.medium
                        ? `${inclusiveLanguage.severity_counts.medium} med`
                        : '',
                      inclusiveLanguage.severity_counts?.low
                        ? `${inclusiveLanguage.severity_counts.low} low`
                        : '',
                    ].filter(Boolean).join(' · ')}
                  </div>
                </div>
              </div>
              <ul className="prs-incl-list" style={{ marginTop: 8, padding: 0, listStyle: 'none' }}>
                {(inclusiveLanguage.issues || []).slice(0, 8).map((issue, idx) => (
                  <li key={idx} style={{ padding: '6px 0', borderTop: idx === 0 ? 'none' : '1px solid #eee' }}>
                    <div style={{ fontSize: 12, fontWeight: 600 }}>
                      <code>{issue.matched_text || issue.term}</code>
                      <span style={{ marginLeft: 8, color: '#666', fontWeight: 400 }}>
                        {`→ ${issue.suggestion || __('Consider alternative', 'prorank-seo')}`}
                      </span>
                    </div>
                    {issue.context && (
                      <div style={{ fontSize: 11, color: '#666', marginTop: 2 }}>
                        {issue.context}
                      </div>
                    )}
                  </li>
                ))}
                {inclusiveLanguage.truncated && (
                  <li style={{ padding: '6px 0', fontSize: 11, color: '#666' }}>
                    {__('More matches not shown.', 'prorank-seo')}
                  </li>
                )}
              </ul>
            </>
          )}
        </div>
      )}

      {/* Issues */}
      {analysisSettings.enable_ai_insights && analysis?.structure_score?.issues?.length > 0 && (
        <div className="prs-sec">
          <h4 className="prs-title">Issues ({analysis.structure_score.issues.length})</h4>
          <div className="prs-issues">
            {analysis.structure_score.issues.slice(0, 5).map((issue, i) => (
              <div key={i} className="prs-issue">
                <span className="prs-dot"></span>
                <span>{issue}</span>
              </div>
            ))}
          </div>
        </div>
      )}
    </div>
  );
};

export default ContentAnalysisPanel;
