/**
 * Issues Page Component
 * 
 * Organized, filterable list of all SEO issues
 */

import React, { useState, useMemo } from 'react';
import { __, sprintf } from '@wordpress/i18n';
import {
  Card,
  CardBody,
  CardHeader,
  Button,
  Spinner,
  TextControl,
  SelectControl,
  Notice,
  Icon,
  __experimentalHeading as Heading,
  __experimentalText as Text,
  Flex,
  FlexItem,
  FlexBlock,
} from '@wordpress/components';
import { check, warning, info, closeSmall, arrowRight, external } from '@wordpress/icons';

const normalizeIssueKey = (value) => String(value || '')
  .trim()
  .toLowerCase()
  .replace(/[\s-]+/g, '_')
  .replace(/[^a-z0-9_]/g, '');

const humanizeIssueKey = (value) => String(value || '')
  .replace(/[_-]+/g, ' ')
  .replace(/\b\w/g, (char) => char.toUpperCase())
  .trim();

const getIssueSubTypeKey = (issue) => normalizeIssueKey(
  issue?.subType
  || issue?.sub_type
  || issue?.subtype
  || issue?.ruleId
  || issue?.rule_id
  || issue?.data?.ruleId
);

const isAxeCoreIssue = (issue) => {
  const sourceKey = normalizeIssueKey(issue?.source || issue?.data?.source);
  const typeKey = normalizeIssueKey(issue?.type || issue?.issue_type);
  const subTypeKey = getIssueSubTypeKey(issue);

  return sourceKey === 'axe_core'
    || subTypeKey.startsWith('axe_')
    || (typeKey === 'accessibility' && Boolean(subTypeKey));
};

const SITE_WIDE_ISSUE_TYPES = new Set([
  'plugins_need_updates',
  'potential_plugin_conflict',
  'database_optimization',
  'security_headers',
  'ssl_certificate',
  'mixed_content',
]);

const CRAWL_SERVER_ISSUE_TYPES = new Set([
  'connectivity',
  'crawl_fetch_failed',
  'crawl_timeout',
  'crawl_error',
  'server_response_error',
  'http_status',
]);

const KNOWN_CATEGORY_KEYS = [
  'technical_seo',
  'on_page_seo',
  'performance',
  'security',
  'content',
  'accessibility',
  'wordpress',
];

const normalizeIssueUrl = (url) => {
  const value = String(url || '').trim();
  if (!value) {
    return '';
  }

  if (value.includes('?_site_level_checks')) {
    return '';
  }

  return value;
};

const formatDurationMs = (value) => {
  const numericValue = Number(value);
  if (!Number.isFinite(numericValue)) {
    return String(value || '');
  }

  if (numericValue >= 1000) {
    return `${(numericValue / 1000).toFixed(2)}s`;
  }

  return `${Math.round(numericValue)}ms`;
};

const formatAuditText = (value) => {
  const text = String(value || '').trim();
  if (!text) {
    return '';
  }

  return text
    .replace(/TTFB is\s+([0-9.]+)ms\s+\(recommended:\s*<\s*600ms\)/i, (_match, ms) => (
      sprintf(
        __('TTFB is %1$s (recommended: under %2$s)', 'prorank-seo'),
        formatDurationMs(ms),
        formatDurationMs(600)
      )
    ))
    .replace(/^([0-9.]+)ms$/i, (_match, ms) => formatDurationMs(ms))
    .replace(/^<\s*([0-9.]+)ms$/i, (_match, ms) => (
      sprintf(__('under %s', 'prorank-seo'), formatDurationMs(ms))
    ));
};

const IssuesPage = ({
  issues = [],
  issuesMeta = null,
  isLoading = false,
  auditStatus = null,
  onFixIssue,
  onIgnoreIssue,
  serverSeverityFilter = null,
  serverCategoryFilter = null,
  onSeverityFilterChange = null,
  onCategoryFilterChange = null,
}) => {
  const [searchTerm, setSearchTerm] = useState('');
  const [severityFilter, setSeverityFilter] = useState('all');
  const [categoryFilter, setCategoryFilter] = useState('all');
  const [expandedIssue, setExpandedIssue] = useState(null);
  const [sortBy, setSortBy] = useState('severity');
  const activeSeverityFilter = serverSeverityFilter ?? severityFilter;
  const activeCategoryFilter = serverCategoryFilter ?? categoryFilter;

  const handleSeverityFilterChange = (value) => {
    setSeverityFilter(value);
    if (typeof onSeverityFilterChange === 'function') {
      onSeverityFilterChange(value);
    }
  };

  const handleCategoryFilterChange = (value) => {
    setCategoryFilter(value);
    if (typeof onCategoryFilterChange === 'function') {
      onCategoryFilterChange(value);
    }
  };

  // Severity order for sorting
  const severityOrder = { critical: 0, high: 1, medium: 2, low: 3, warning: 4 };

  const getIssueTypeKey = (issue) => normalizeIssueKey(
    (isAxeCoreIssue(issue) ? getIssueSubTypeKey(issue) : '')
    || issue?.type
    || issue?.issue_type
    || issue?.issue_key
    || issue?.key
    || issue?.title
  );

  const getIssueCategory = (issue) => {
    const rawCategory = normalizeIssueKey(
      issue?.category
      || issue?.issue_category
      || issue?.issueCategory
    );
    const typeKey = getIssueTypeKey(issue);

    if (
      isAxeCoreIssue(issue)
      || rawCategory === 'accessibility'
      || typeKey === 'accessibility'
      || typeKey.startsWith('a11y_')
      || typeKey.startsWith('axe_')
    ) {
      return 'accessibility';
    }

    const explicitCategory = normalizeIssueKey(
      issue?.display_category
      || rawCategory
      || issue?.displayCategory
    );

    if (explicitCategory && explicitCategory !== 'other') {
      return explicitCategory;
    }

    const categoryMap = {
      connectivity: 'technical_seo',
      redirect_chain: 'technical_seo',
      redirect_loop: 'technical_seo',
      orphaned_page: 'on_page_seo',
      missing_meta_description: 'on_page_seo',
      missing_title: 'on_page_seo',
      duplicate_title: 'on_page_seo',
      duplicate_meta_description: 'on_page_seo',
      plugins_need_updates: 'wordpress',
      potential_plugin_conflict: 'wordpress',
      database_optimization: 'wordpress',
      security_headers: 'security',
      mixed_content: 'security',
      ssl_certificate: 'security',
      page_speed: 'performance',
      core_web_vitals: 'performance',
      css_import_usage: 'performance',
      duplicate_content: 'content',
      thin_content: 'content',
      low_lexical_diversity: 'content',
      multiple_h1: 'content',
      heading_levels_skipped: 'content',
      iframes_missing_title: 'accessibility',
      a11y_iframe_no_title: 'accessibility',
      a11y_missing_lang: 'accessibility',
      links_without_accessible_text: 'accessibility',
    };

    if (categoryMap[typeKey]) {
      return categoryMap[typeKey];
    }

    if (typeKey.includes('plugin') || typeKey.includes('wordpress') || typeKey.includes('database')) {
      return 'wordpress';
    }

    if (typeKey.includes('security') || typeKey.includes('ssl') || typeKey.includes('mixed')) {
      return 'security';
    }

    if (typeKey.includes('speed') || typeKey.includes('performance') || typeKey.includes('cache') || typeKey.includes('cwv')) {
      return 'performance';
    }

    if (typeKey.includes('content') || typeKey.includes('title') || typeKey.includes('meta') || typeKey.includes('heading')) {
      return 'content';
    }

    return 'technical_seo';
  };

  const getIssueDisplayTitle = (issue) => {
    const explicitTitle = String(issue?.title || '').trim();
    const typeKey = getIssueTypeKey(issue);

    const typeLabels = {
      connectivity: __('Server response could not be read by the audit crawler', 'prorank-seo'),
      orphaned_page: __('Orphaned page', 'prorank-seo'),
      plugins_need_updates: __('Plugins need updates', 'prorank-seo'),
      potential_plugin_conflict: __('Potential plugin conflict', 'prorank-seo'),
      security_headers: __('Missing security headers', 'prorank-seo'),
      mixed_content: __('Mixed content detected', 'prorank-seo'),
      css_import_usage: __('CSS @import usage', 'prorank-seo'),
      duplicate_content: __('Duplicate content', 'prorank-seo'),
      low_lexical_diversity: __('Low lexical diversity', 'prorank-seo'),
      links_without_accessible_text: __('Links without accessible text', 'prorank-seo'),
      iframes_missing_title: __('Iframes missing title', 'prorank-seo'),
      a11y_iframe_no_title: __('Iframes missing title', 'prorank-seo'),
      a11y_missing_lang: __('Missing html lang attribute', 'prorank-seo'),
      multiple_h1: __('Multiple H1 headings', 'prorank-seo'),
      heading_levels_skipped: __('Heading levels skipped', 'prorank-seo'),
    };

    if (typeLabels[typeKey]) {
      return typeLabels[typeKey];
    }

    if (explicitTitle && !/^[a-z0-9_ -]+$/i.test(explicitTitle)) {
      return explicitTitle;
    }

    if (explicitTitle && !explicitTitle.includes('_')) {
      return explicitTitle;
    }

    if (typeKey) {
      return humanizeIssueKey(typeKey);
    }

    if (explicitTitle) {
      return humanizeIssueKey(explicitTitle);
    }

    return __('Issue', 'prorank-seo');
  };

  const getIssueDescription = (issue) => {
    const typeKey = getIssueTypeKey(issue);
    const description = String(issue?.description || '').trim();
    if (description) {
      return formatAuditText(description);
    }

    if (typeKey === 'connectivity') {
      return __('The audit crawler could not decode the server response. This usually points to broken compression or caching headers rather than a problem with the page content itself.', 'prorank-seo');
    }

    if (typeKey === 'plugins_need_updates') {
      return __('Installed plugins have updates available. This is a site-wide maintenance item, not a page-specific content issue.', 'prorank-seo');
    }

    if (typeKey === 'potential_plugin_conflict') {
      return __('Another plugin may overlap with ProRank features. Review overlapping optimization or caching features before enabling both together.', 'prorank-seo');
    }

    const message = String(issue?.message || '').trim();
    if (!message) {
      return '';
    }

    return message === getIssueDisplayTitle(issue) ? '' : formatAuditText(message);
  };

  const getIssueTechnicalDetails = (issue) => {
    const message = String(issue?.message || '').trim();
    const description = String(issue?.description || '').trim();
    if (!message || message === description) {
      return '';
    }
    return formatAuditText(message);
  };

  const getIssueUrls = (issue) => {
    const rawUrls = Array.isArray(issue?.affected_urls) && issue.affected_urls.length
      ? issue.affected_urls
      : Array.isArray(issue?.urls) && issue.urls.length
        ? issue.urls
        : Array.isArray(issue?.pages) && issue.pages.length
          ? issue.pages.map((page) => (typeof page === 'string' ? page : page?.url))
          : issue?.url
            ? [issue.url]
            : [];

    return Array.from(new Set(rawUrls.map(normalizeIssueUrl).filter(Boolean)));
  };

  const isSiteLevelIssue = (issue) => {
    if (SITE_WIDE_ISSUE_TYPES.has(getIssueTypeKey(issue))) {
      return true;
    }

    const rawUrls = []
      .concat(Array.isArray(issue?.affected_urls) ? issue.affected_urls : [])
      .concat(Array.isArray(issue?.urls) ? issue.urls : [])
      .concat(typeof issue?.url === 'string' ? [issue.url] : []);

    return rawUrls.some((url) => String(url || '').includes('?_site_level_checks'));
  };

  const isCrawlServerIssue = (issue) => {
    const typeKey = getIssueTypeKey(issue);
    if (CRAWL_SERVER_ISSUE_TYPES.has(typeKey)) {
      return true;
    }

    if (
      typeKey.includes('connectivity')
      || typeKey.includes('crawl')
      || typeKey.includes('fetch')
      || typeKey.includes('timeout')
      || typeKey.includes('http_status')
    ) {
      return true;
    }

    const explicitCategory = normalizeIssueKey(
      issue?.display_category
      || issue?.category
      || issue?.issue_category
      || issue?.displayCategory
      || issue?.issueCategory
    );

    return explicitCategory === 'crawl' || explicitCategory === 'server';
  };

  const getIssueScopeType = (issue) => {
    if (isSiteLevelIssue(issue)) {
      return 'sitewide';
    }

    if (isCrawlServerIssue(issue)) {
      return 'crawl';
    }

    return 'page';
  };

  const getIssueOccurrenceCount = (issue) => {
    const rawCount = Number(
      issue?.occurrence_count
      ?? issue?.occurrences
      ?? issue?.count
      ?? issue?.affected_urls_count
      ?? issue?.affectedUrls
      ?? 0
    );

    return Number.isFinite(rawCount) && rawCount > 0 ? rawCount : 1;
  };

  const getIssueAffectedPageCount = (issue) => {
    const rawCount = Number(
      issue?.affected_urls_count
      ?? issue?.affectedUrls
      ?? issue?.affected_pages
      ?? issue?.affectedPages
      ?? 0
    );

    return Number.isFinite(rawCount) && rawCount > 0 ? rawCount : 0;
  };

  const getIssueCurrentValue = (issue) => formatAuditText(issue?.current_value || issue?.currentValue);
  const getIssueRecommendedValue = (issue) => formatAuditText(issue?.recommended_value || issue?.recommendedValue);

  const getIssueUrlListLabel = (issue) => {
    const urls = getIssueUrls(issue);
    const occurrences = getIssueOccurrenceCount(issue);
    const isSampleList = occurrences > urls.length;

    if (isSampleList) {
      return sprintf(
        urls.length === 1
          ? __('Sample affected page (%d)', 'prorank-seo')
          : __('Sample affected pages (%d)', 'prorank-seo'),
        urls.length
      );
    }

    return sprintf(
      urls.length === 1
        ? __('Affected page (%d)', 'prorank-seo')
        : __('Affected pages (%d)', 'prorank-seo'),
      urls.length
    );
  };

  const reportSummary = issuesMeta?.report_summary || null;
  const reportSummaryFindings = Array.isArray(reportSummary?.findings) ? reportSummary.findings : [];
  const hasServerFilters = Boolean(
    activeSeverityFilter !== 'all'
    || activeCategoryFilter !== 'all'
    || (issuesMeta?.filters?.type && issuesMeta.filters.type !== 'all')
  );
  const reportViewIssues = useMemo(() => (
    reportSummaryFindings.map((finding, index) => ({
      id: finding?.key || `report-finding-${index}`,
      type: finding?.key || finding?.type || finding?.title,
      issue_type: finding?.key || finding?.type || finding?.title,
      severity: finding?.severity || 'warning',
      category: finding?.category || 'content',
      display_category: finding?.category || 'content',
      title: finding?.title,
      description: finding?.description,
      how_to_fix: finding?.recommendation,
      recommendation: finding?.recommendation,
      impact: finding?.impact,
      count: Number(finding?.occurrences ?? finding?.affected_urls ?? 1) || 1,
      affected_urls_count: Number(finding?.affected_urls ?? finding?.occurrences ?? 0) || 0,
      affected_urls: Array.isArray(finding?.sample_urls) ? finding.sample_urls : [],
      urls: Array.isArray(finding?.sample_urls) ? finding.sample_urls : [],
      priority_score: finding?.priority_score,
    }))
  ), [reportSummaryFindings]);
  const useReportSummaryView = !hasServerFilters && reportViewIssues.length > 0;
  const sourceIssues = useReportSummaryView ? reportViewIssues : issues;

  const getIssueScopeLabel = (issue) => {
    const scopeType = getIssueScopeType(issue);

    if (scopeType === 'sitewide') {
      return __('Site-wide check', 'prorank-seo');
    }

    if (scopeType === 'crawl') {
      const urls = getIssueUrls(issue);
      if (urls.length > 0) {
        return sprintf(
          urls.length === 1
            ? __('Crawler/server issue affecting %d page', 'prorank-seo')
            : __('Crawler/server issue affecting %d pages', 'prorank-seo'),
          urls.length
        );
      }
      return __('Crawler/server check', 'prorank-seo');
    }

    const urls = getIssueUrls(issue);
    const occurrences = getIssueOccurrenceCount(issue);
    const affectedPageCount = getIssueAffectedPageCount(issue);

    if (affectedPageCount > urls.length) {
      return sprintf(
        affectedPageCount === 1 ? __('%d page affected', 'prorank-seo') : __('%d pages affected', 'prorank-seo'),
        affectedPageCount
      );
    }

    if (urls.length > 0) {
      if (occurrences > urls.length) {
        return sprintf(
          occurrences === 1 ? __('%d finding across pages', 'prorank-seo') : __('%d findings across pages', 'prorank-seo'),
          occurrences
        );
      }

      return sprintf(
        urls.length === 1 ? __('%d page affected', 'prorank-seo') : __('%d pages affected', 'prorank-seo'),
        urls.length
      );
    }

    return __('Scope not available', 'prorank-seo');
  };

  const getIssueRowKey = (issue, index) => String(
    issue?.id
    || issue?.issue_id
    || issue?.uuid
    || getIssueSubTypeKey(issue)
    || `${getIssueTypeKey(issue) || 'issue'}-${index}`
  );

  // Filter and sort issues
  const filteredIssues = useMemo(() => {
    let filtered = [...sourceIssues];

    // Search filter
    if (searchTerm) {
      const term = searchTerm.toLowerCase();
      filtered = filtered.filter(issue =>
        getIssueDisplayTitle(issue).toLowerCase().includes(term) ||
        getIssueDescription(issue).toLowerCase().includes(term) ||
        getIssueUrls(issue).some((url) => String(url || '').toLowerCase().includes(term))
      );
    }

    // Severity filter
    if (activeSeverityFilter !== 'all') {
      filtered = filtered.filter(issue => issue.severity === activeSeverityFilter);
    }

    // Category filter
    if (activeCategoryFilter !== 'all') {
      filtered = filtered.filter(issue => getIssueCategory(issue) === activeCategoryFilter);
    }

    // Sort
    filtered.sort((a, b) => {
      if (sortBy === 'severity') {
        return (severityOrder[a.severity] || 5) - (severityOrder[b.severity] || 5);
      }
      if (sortBy === 'category') {
        return getIssueCategory(a).localeCompare(getIssueCategory(b));
      }
      return 0;
    });

    return filtered;
  }, [sourceIssues, searchTerm, activeSeverityFilter, activeCategoryFilter, sortBy]);

  const displayIssues = useMemo(() => {
    const grouped = new Map();

    filteredIssues.forEach((issue, index) => {
      const urls = getIssueUrls(issue);
      const key = [
        issue?.severity || 'unknown',
        getIssueScopeType(issue),
        getIssueCategory(issue),
        getIssueTypeKey(issue),
        getIssueDisplayTitle(issue),
        getIssueDescription(issue),
        issue?.current_value || issue?.currentValue || '',
        issue?.recommended_value || issue?.recommendedValue || '',
      ].join('|');

      const existing = grouped.get(key);
      if (!existing) {
        grouped.set(key, {
          ...issue,
          id: issue?.id || `issue-group-${index}`,
          affected_urls: urls,
          urls,
          occurrence_count: getIssueOccurrenceCount(issue),
        });
        return;
      }

      const mergedUrls = Array.from(new Set([
        ...getIssueUrls(existing),
        ...urls,
      ].filter(Boolean)));

      grouped.set(key, {
        ...existing,
        affected_urls: mergedUrls,
        urls: mergedUrls,
        occurrence_count: Number(existing.occurrence_count || 1) + getIssueOccurrenceCount(issue),
      });
    });

    return Array.from(grouped.values());
  }, [filteredIssues]);

  // Group issues by type for summary
  const loadedIssueSummary = useMemo(() => {
    const summary = { critical: 0, high: 0, medium: 0, low: 0, warning: 0 };
    sourceIssues.forEach(issue => {
      if (summary[issue.severity] !== undefined) {
        summary[issue.severity]++;
      }
    });
    return summary;
  }, [sourceIssues]);

  const serverFilters = issuesMeta?.filters || {};
  const hasServerIssueFilter = Boolean(
    (serverFilters.severity && serverFilters.severity !== 'all')
    || (serverFilters.category && serverFilters.category !== 'all')
    || (serverFilters.type && serverFilters.type !== 'all')
  );
  const issueCounts = issuesMeta?.issue_counts || {};
  const rawPaginationTotal = Number(issuesMeta?.pagination?.total ?? issues.length) || issues.length;
  const severityOnlyServerFilter = hasServerIssueFilter
    && activeSeverityFilter !== 'all'
    && activeCategoryFilter === 'all'
    && (!serverFilters.type || serverFilters.type === 'all');
  const severityMatchTotal = severityOnlyServerFilter
    ? Number(issueCounts[activeSeverityFilter] ?? 0)
    : 0;
  const loadedFindings = useReportSummaryView ? displayIssues.length : issues.length;
  const totalAuditFindings = Number(
    issueCounts.total
    ?? auditStatus?.stats?.total_issues
    ?? auditStatus?.issues?.total
    ?? auditStatus?.total_issues
    ?? rawPaginationTotal
  ) || rawPaginationTotal;
  const matchingFindings = severityMatchTotal > 0
    ? severityMatchTotal
    : (hasServerIssueFilter && rawPaginationTotal === totalAuditFindings ? loadedFindings : rawPaginationTotal);
  const displayedTotalFindings = hasServerIssueFilter ? matchingFindings : totalAuditFindings;
  const isPartialIssuePage = displayedTotalFindings > loadedFindings || Boolean(issuesMeta?.too_large);
  const auditIssueSummary = useMemo(() => {
    if (!isPartialIssuePage) {
      return loadedIssueSummary;
    }

    const counts = issuesMeta?.issue_counts || {};
    const stats = auditStatus?.stats || {};

    return {
      critical: Number(counts.critical ?? stats.critical_issues ?? loadedIssueSummary.critical) || 0,
      high: Number(counts.high ?? stats.high_issues ?? loadedIssueSummary.high) || 0,
      medium: Number(counts.medium ?? stats.medium_issues ?? loadedIssueSummary.medium) || 0,
      low: Number(counts.low ?? stats.low_issues ?? loadedIssueSummary.low) || 0,
      warning: Number(counts.warning ?? stats.warning_issues ?? loadedIssueSummary.warning) || 0,
    };
  }, [auditStatus?.stats, isPartialIssuePage, issuesMeta?.issue_counts, loadedIssueSummary]);
  const actionableAuditFindings = Number(auditIssueSummary.critical || 0) + Number(auditIssueSummary.high || 0);

  // Get unique categories from issues. Partial cloud pages may not contain every
  // category, so include the known category keys to keep server filters reachable.
  const categories = useMemo(() => {
    const cats = new Set(isPartialIssuePage ? KNOWN_CATEGORY_KEYS : []);
    issues.forEach((issue) => cats.add(getIssueCategory(issue)));
    return Array.from(cats).filter(Boolean);
  }, [issues, isPartialIssuePage]);

  // Group filtered issues by category
  const groupedIssues = useMemo(() => {
    const groups = {};
    displayIssues.forEach(issue => {
      const scope = getIssueScopeType(issue);
      const cat = getIssueCategory(issue);

      if (!groups[scope]) {
        groups[scope] = {};
      }

      if (!groups[scope][cat]) {
        groups[scope][cat] = [];
      }

      groups[scope][cat].push(issue);
    });
    return groups;
  }, [displayIssues]);

  const issueSections = useMemo(() => {
    const sectionMeta = {
      page: {
        key: 'page',
        title: __('Page Issues', 'prorank-seo'),
        description: __('Issues tied to specific pages or posts. These are the findings that most directly affect on-page SEO and content quality.', 'prorank-seo'),
      },
      sitewide: {
        key: 'sitewide',
        title: __('Site-wide Checks', 'prorank-seo'),
        description: __('Environment and maintenance checks that apply to the whole WordPress site rather than a single page.', 'prorank-seo'),
      },
      crawl: {
        key: 'crawl',
        title: __('Crawl / Server Errors', 'prorank-seo'),
        description: __('Crawler transport failures and server-response problems. These can affect audit coverage, but they do not always mean the page content itself is broken.', 'prorank-seo'),
      },
    };

    return ['page', 'sitewide', 'crawl']
      .map((scope) => {
        const categoriesMap = groupedIssues[scope] || {};
        const categoryEntries = Object.entries(categoriesMap).sort(([a], [b]) => {
          return getCategoryLabel(a).localeCompare(getCategoryLabel(b));
        });

        const issueCount = categoryEntries.reduce((count, [, scopeIssues]) => count + scopeIssues.length, 0);

        return {
          ...sectionMeta[scope],
          issueCount,
          categories: categoryEntries,
        };
      })
      .filter((section) => section.issueCount > 0);
  }, [groupedIssues]);

  const getSeverityColor = (severity) => {
    const colors = {
      critical: '#dc2626',
      high: '#ea580c',
      medium: '#d97706',
      low: '#2563eb',
      warning: '#6b7280',
    };
    return colors[severity] || '#6b7280';
  };

  const getSeverityBgColor = (severity) => {
    const colors = {
      critical: '#fef2f2',
      high: '#fff7ed',
      medium: '#fffbeb',
      low: '#eff6ff',
      warning: '#f9fafb',
    };
    return colors[severity] || '#f9fafb';
  };

  function getCategoryLabel(cat) {
    const labels = {
      technical_seo: __('Technical SEO', 'prorank-seo'),
      on_page_seo: __('On-Page SEO', 'prorank-seo'),
      performance: __('Performance', 'prorank-seo'),
      security: __('Security', 'prorank-seo'),
      content: __('Content', 'prorank-seo'),
      accessibility: __('Accessibility', 'prorank-seo'),
      wordpress: __('WordPress', 'prorank-seo'),
    };
    return labels[cat] || humanizeIssueKey(cat);
  }

  const hasActiveFilters = Boolean(
    searchTerm
    || activeSeverityFilter !== 'all'
    || activeCategoryFilter !== 'all'
    || sortBy !== 'severity'
  );

  const clearFilters = () => {
    setSearchTerm('');
    handleSeverityFilterChange('all');
    handleCategoryFilterChange('all');
    setSortBy('severity');
  };

  if (auditStatus?.state !== 'completed') {
    return (
      <Card>
        <CardBody>
          <div style={{ textAlign: 'center', padding: '40px 20px' }}>
            <Icon icon={info} size={48} style={{ color: '#6b7280', marginBottom: '16px' }} />
            <Heading level={3} style={{ marginBottom: '8px' }}>
              {__('No Audit Data', 'prorank-seo')}
            </Heading>
            <Text>{__('Run an audit to see issues.', 'prorank-seo')}</Text>
          </div>
        </CardBody>
      </Card>
    );
  }

  return (
    <div className="prorank-issues-page">
      <div className="prorank-audit-hero">
        <div className="prorank-audit-hero__copy">
          <span className="prorank-audit-hero__eyebrow">
            {__('Issue Review', 'prorank-seo')}
          </span>
          <Heading level={2} style={{ margin: '0 0 8px' }}>
            {useReportSummaryView
              ? __('Prioritised audit findings grouped by impact and scope', 'prorank-seo')
              : __('Audit findings grouped by impact and scope', 'prorank-seo')}
          </Heading>
          <Text className="prorank-audit-hero__description">
            {useReportSummaryView
              ? __('This view uses the same grouped report findings as the ProRank admin report, so repeated page-level noise is collapsed into issue types and priority actions.', 'prorank-seo')
              : __('Page issues, site-wide checks, and crawler/server failures are separated so the audit reads like a product report instead of a debug dump.', 'prorank-seo')}
          </Text>
        </div>
        <div className="prorank-audit-hero__metrics">
          <div className="prorank-audit-hero__metric">
            <span className="prorank-audit-hero__metric-value">{useReportSummaryView ? displayIssues.length : filteredIssues.length}</span>
            <span className="prorank-audit-hero__metric-label">
              {useReportSummaryView
                ? __('Priority issue types', 'prorank-seo')
                : isPartialIssuePage ? __('Loaded findings', 'prorank-seo') : __('Visible findings', 'prorank-seo')}
            </span>
          </div>
          <div className="prorank-audit-hero__metric">
            <span className="prorank-audit-hero__metric-value">
              {useReportSummaryView ? actionableAuditFindings.toLocaleString() : displayedTotalFindings.toLocaleString()}
            </span>
            <span className="prorank-audit-hero__metric-label">
              {useReportSummaryView
                ? __('Actionable findings', 'prorank-seo')
                : hasServerIssueFilter ? __('Matching findings', 'prorank-seo') : __('Total findings', 'prorank-seo')}
            </span>
          </div>
          <div className="prorank-audit-hero__metric">
            <span className="prorank-audit-hero__metric-value">
              {useReportSummaryView ? totalAuditFindings.toLocaleString() : issueSections.length}
            </span>
            <span className="prorank-audit-hero__metric-label">
              {useReportSummaryView
                ? __('Raw findings', 'prorank-seo')
                : isPartialIssuePage ? __('Loaded sections', 'prorank-seo') : __('Sections', 'prorank-seo')}
            </span>
          </div>
        </div>
      </div>

      {isPartialIssuePage && (
        <Notice status="info" isDismissible={false}>
          <p>
            {useReportSummaryView
              ? sprintf(
                  __('Showing %1$d priority issue types from %2$d actionable findings. Raw crawler findings total %3$d, including lower-priority monitor items.', 'prorank-seo'),
                  displayIssues.length,
                  actionableAuditFindings.toLocaleString(),
                  totalAuditFindings.toLocaleString()
                )
              : hasServerIssueFilter
              ? sprintf(
                  __('This list contains the first %1$d loaded findings matching the selected server filters. The full audit contains %2$d findings.', 'prorank-seo'),
                  loadedFindings,
                  totalAuditFindings
                )
              : sprintf(
                  __('This list contains the first %1$d loaded findings. The severity cards show totals for the full %2$d-finding cloud audit.', 'prorank-seo'),
                  loadedFindings,
                  totalAuditFindings
                )}
          </p>
        </Notice>
      )}

      <div className="prorank-audit-summary-grid">
        {[
          { key: 'critical', label: __('Critical', 'prorank-seo'), color: '#dc2626', bg: '#fef2f2' },
          { key: 'high', label: __('High', 'prorank-seo'), color: '#ea580c', bg: '#fff7ed' },
          { key: 'medium', label: __('Medium', 'prorank-seo'), color: '#ca8a04', bg: '#fefce8' },
          { key: 'low', label: __('Low', 'prorank-seo'), color: '#16a34a', bg: '#f0fdf4' },
          { key: 'warning', label: __('Warnings', 'prorank-seo'), color: '#6b7280', bg: '#f9fafb' },
        ].map(({ key, label, color, bg }) => (
          <Card
            key={key}
            className={`prorank-audit-summary-card ${activeSeverityFilter === key ? 'is-active' : ''}`}
            data-severity={key}
            onClick={() => handleSeverityFilterChange(activeSeverityFilter === key ? 'all' : key)}
          >
            <CardBody className="prorank-audit-summary-card__body">
              <div className="prorank-audit-summary-card__value" style={{ color }}>
                {auditIssueSummary[key].toLocaleString()}
              </div>
              <div className="prorank-audit-summary-card__label">
                {label}
              </div>
              {activeSeverityFilter === key && (
                <div className="prorank-audit-summary-card__state" style={{ color }}>
                  {__('Filtering active', 'prorank-seo')}
                </div>
              )}
              {activeSeverityFilter !== key && isPartialIssuePage && (
                <div className="prorank-audit-summary-card__state" style={{ color }}>
                  {__('Audit total', 'prorank-seo')}
                </div>
              )}
            </CardBody>
          </Card>
        ))}
      </div>

      <Card className="prorank-audit-toolbar-card">
        <CardBody>
          <div className="prorank-audit-toolbar">
            <div className="prorank-audit-toolbar__header">
              <div>
                <Heading level={4} style={{ margin: '0 0 4px' }}>
                  {useReportSummaryView
                    ? __('Refine priority issue types', 'prorank-seo')
                    : isPartialIssuePage ? __('Refine loaded findings', 'prorank-seo') : __('Refine the issue list', 'prorank-seo')}
                </Heading>
                <Text className="prorank-audit-toolbar__copy">
                  {useReportSummaryView
                    ? __('Search and sort the priority list. Use severity or category filters when you need to inspect raw matching findings.', 'prorank-seo')
                    : hasServerIssueFilter
                    ? __('Search and sort the loaded server-filtered findings while keeping the grouped audit layout intact.', 'prorank-seo')
                    : isPartialIssuePage
                      ? __('Search, filter, and sort the loaded first page while keeping the grouped audit layout intact.', 'prorank-seo')
                    : __('Search, filter, and sort while keeping the grouped audit layout intact.', 'prorank-seo')}
                </Text>
              </div>
              {hasActiveFilters && (
                <Button variant="secondary" onClick={clearFilters}>
                  {__('Clear filters', 'prorank-seo')}
                </Button>
              )}
            </div>
            <Flex className="prorank-audit-toolbar__filters">
            <FlexBlock>
              <TextControl
                label={__('Search Issues', 'prorank-seo')}
                value={searchTerm}
                onChange={setSearchTerm}
                placeholder={__('Search by title, description, or URL...', 'prorank-seo')}
                __next40pxDefaultSize
                __nextHasNoMarginBottom
              />
            </FlexBlock>
            <FlexItem>
              <SelectControl
                label={__('Severity', 'prorank-seo')}
                value={activeSeverityFilter}
                options={[
                  { label: __('All Severities', 'prorank-seo'), value: 'all' },
                  { label: __('Critical', 'prorank-seo'), value: 'critical' },
                  { label: __('High', 'prorank-seo'), value: 'high' },
                  { label: __('Medium', 'prorank-seo'), value: 'medium' },
                  { label: __('Low', 'prorank-seo'), value: 'low' },
                  { label: __('Warning', 'prorank-seo'), value: 'warning' },
                ]}
                onChange={handleSeverityFilterChange}
                __next40pxDefaultSize
                __nextHasNoMarginBottom
              />
            </FlexItem>
            <FlexItem>
              <SelectControl
                label={__('Category', 'prorank-seo')}
                value={activeCategoryFilter}
                options={[
                  { label: __('All Categories', 'prorank-seo'), value: 'all' },
                  ...categories.map(cat => ({ 
                    label: getCategoryLabel(cat), 
                    value: cat 
                  }))
                ]}
                onChange={handleCategoryFilterChange}
                __next40pxDefaultSize
                __nextHasNoMarginBottom
              />
            </FlexItem>
            <FlexItem>
              <SelectControl
                label={__('Sort By', 'prorank-seo')}
                value={sortBy}
                options={[
                  { label: __('Severity', 'prorank-seo'), value: 'severity' },
                  { label: __('Category', 'prorank-seo'), value: 'category' },
                ]}
                onChange={setSortBy}
                __next40pxDefaultSize
                __nextHasNoMarginBottom
              />
            </FlexItem>
            </Flex>
          </div>
        </CardBody>
      </Card>

      <div className="prorank-audit-results-bar">
        <span>
        {hasServerIssueFilter
          ? sprintf(
              __('Showing %1$d loaded matching findings from %2$d matches (%3$d total audit findings) across %4$d loaded sections', 'prorank-seo'),
              filteredIssues.length,
              matchingFindings,
              totalAuditFindings,
              issueSections.length
            )
          : useReportSummaryView
          ? sprintf(
              __('Showing %1$d priority issue types from %2$d actionable findings (%3$d raw findings in the full audit)', 'prorank-seo'),
              displayIssues.length,
              actionableAuditFindings.toLocaleString(),
              totalAuditFindings.toLocaleString()
            )
          : isPartialIssuePage
          ? sprintf(
              __('Showing %1$d loaded findings from %2$d total findings across %3$d loaded sections', 'prorank-seo'),
                filteredIssues.length,
                totalAuditFindings,
                issueSections.length
              )
            : sprintf(__('Showing %1$d of %2$d findings across %3$d sections', 'prorank-seo'), filteredIssues.length, issues.length, issueSections.length)}
        </span>
        {hasActiveFilters && (
          <span className="prorank-audit-results-bar__tag">
            {__('Filtered view', 'prorank-seo')}
          </span>
        )}
      </div>

      {isLoading && (
        <Card className="prorank-audit-empty-card">
          <CardBody className="prorank-audit-empty-card__body">
            <Spinner />
            <Text style={{ marginTop: '16px' }}>{__('Loading issues...', 'prorank-seo')}</Text>
          </CardBody>
        </Card>
      )}

      {!isLoading && filteredIssues.length === 0 && (
        <Card className="prorank-audit-empty-card">
          <CardBody>
            <Notice status="success" isDismissible={false}>
              <p>
                {sourceIssues.length === 0 
                  ? __('No issues found! Your site is in great shape.', 'prorank-seo')
                  : __('No issues match your filters.', 'prorank-seo')
                }
              </p>
            </Notice>
          </CardBody>
        </Card>
      )}

      {!isLoading && issueSections.map((section) => (
        <section key={section.key} className={`prorank-audit-section prorank-audit-section--${section.key}`}>
          <div className="prorank-audit-section__header">
            <div>
            <Heading level={3} style={{ marginBottom: '4px' }}>
              {section.title}
            </Heading>
              <Text className="prorank-audit-section__description">{section.description}</Text>
            </div>
            <div className="prorank-audit-section__badge">
              {sprintf(
                useReportSummaryView
                  ? (section.issueCount === 1 ? __('%d issue type', 'prorank-seo') : __('%d issue types', 'prorank-seo'))
                  : (section.issueCount === 1 ? __('%d finding', 'prorank-seo') : __('%d findings', 'prorank-seo')),
                section.issueCount
              )}
            </div>
          </div>

          {section.categories.map(([category, categoryIssues]) => (
            <Card key={`${section.key}-${category}`} className="prorank-audit-category-card">
              <CardHeader className="prorank-audit-category-card__header">
                <Flex justify="space-between" align="center">
                  <div>
                    <Heading level={4} style={{ margin: '0 0 4px' }}>
                      {getCategoryLabel(category)}
                    </Heading>
                    <Text className="prorank-audit-category-card__copy">
                      {section.key === 'sitewide'
                        ? __('Environment and maintenance checks grouped under this category.', 'prorank-seo')
                        : section.key === 'crawl'
                          ? __('Crawler and server failures grouped under this category.', 'prorank-seo')
                          : __('Page-level findings grouped under this category.', 'prorank-seo')}
                    </Text>
                  </div>
                  <span className="prorank-audit-category-card__count">
                    {sprintf(
                      useReportSummaryView
                        ? (categoryIssues.length === 1 ? __('%d issue type', 'prorank-seo') : __('%d issue types', 'prorank-seo'))
                        : (categoryIssues.length === 1 ? __('%d finding', 'prorank-seo') : __('%d findings', 'prorank-seo')),
                      categoryIssues.length
                    )}
                  </span>
                </Flex>
              </CardHeader>
              <CardBody className="prorank-audit-category-card__body">
                {categoryIssues.map((issue, index) => (
                  <div
                    key={getIssueRowKey(issue, index)}
                    className={`prorank-audit-issue-row ${expandedIssue === getIssueRowKey(issue, index) ? 'is-expanded' : ''}`}
                    data-severity={issue.severity}
                    style={{
                      borderBottom: index < categoryIssues.length - 1 ? '1px solid #e2e8f0' : 'none',
                    }}
                  >
                    <div
                      className="prorank-audit-issue-row__trigger"
                      onClick={() => setExpandedIssue(expandedIssue === getIssueRowKey(issue, index) ? null : getIssueRowKey(issue, index))}
                    >
                      <Flex align="center" gap={3}>
                        <div className="prorank-audit-issue-row__severity">
                          {issue.severity}
                        </div>

                        <FlexBlock className="prorank-audit-issue-row__content">
                          <div className="prorank-audit-issue-row__title">
                            {getIssueDisplayTitle(issue)}
                          </div>
                          <div className="prorank-audit-issue-row__meta">
                            {getIssueScopeLabel(issue)}
                          </div>
                          {getIssueDescription(issue) && (
                            <div className="prorank-audit-issue-row__description">
                              {getIssueDescription(issue)}
                            </div>
                          )}
                        </FlexBlock>

                        <div className="prorank-audit-issue-row__arrow">
                          <Icon icon={arrowRight} size={20} />
                        </div>
                      </Flex>
                    </div>

                    {expandedIssue === getIssueRowKey(issue, index) && (
                      <div className="prorank-audit-issue-row__panel">
                        <div className="prorank-audit-issue-row__panel-card">
                          {getIssueDescription(issue) && (
                            <div className="prorank-audit-detail-card">
                              <strong className="prorank-audit-detail-card__label">
                                {__('Why this matters', 'prorank-seo')}
                              </strong>
                              <p style={{ margin: 0, color: '#4b5563' }}>{getIssueDescription(issue)}</p>
                            </div>
                          )}

                          {getIssueTechnicalDetails(issue) && (
                            <div className="prorank-audit-detail-card prorank-audit-detail-card--technical">
                              <strong className="prorank-audit-detail-card__label">
                                {__('Technical details', 'prorank-seo')}
                              </strong>
                              <p style={{ margin: 0, color: '#64748b', fontFamily: 'monospace', fontSize: '12px', wordBreak: 'break-word' }}>
                                {getIssueTechnicalDetails(issue)}
                              </p>
                            </div>
                          )}

                          {getIssueUrls(issue).length > 0 && (
                            <div className="prorank-audit-url-card">
                              <strong className="prorank-audit-detail-card__label">
                                {getIssueUrlListLabel(issue)}
                              </strong>
                              <div style={{ display: 'grid', gap: '8px' }}>
                                {getIssueUrls(issue).map((url) => (
                                  <a
                                    key={url}
                                    href={url}
                                    target="_blank"
                                    rel="noopener noreferrer"
                                    onClick={(event) => event.stopPropagation()}
                                    className="prorank-audit-url-list__item"
                                  >
                                    <span>{url}</span>
                                    <Icon icon={external} size={12} />
                                  </a>
                                ))}
                              </div>
                            </div>
                          )}

                          {getIssueScopeType(issue) === 'sitewide' && getIssueUrls(issue).length === 0 && (
                            <div className="prorank-audit-inline-note">
                              {__('This issue was detected during a site-wide environment check.', 'prorank-seo')}
                            </div>
                          )}

                          {getIssueScopeType(issue) === 'crawl' && (
                            <div className="prorank-audit-inline-note prorank-audit-inline-note--warning">
                              {__('This is a crawler/server response problem. Fix the transport layer first, then rerun the audit before treating it like a page-content issue.', 'prorank-seo')}
                            </div>
                          )}

                          {(getIssueCurrentValue(issue) || getIssueRecommendedValue(issue)) && (
                            <div className="prorank-audit-value-grid">
                              {getIssueCurrentValue(issue) && (
                                <div className="prorank-audit-value-card prorank-audit-value-card--current">
                                  <strong className="prorank-audit-value-card__label">
                                    {__('Current', 'prorank-seo')}
                                  </strong>
                                  <code style={{ fontSize: '13px', wordBreak: 'break-all' }}>
                                    {getIssueCurrentValue(issue)}
                                  </code>
                                </div>
                              )}
                              {getIssueRecommendedValue(issue) && (
                                <div className="prorank-audit-value-card prorank-audit-value-card--recommended">
                                  <strong className="prorank-audit-value-card__label">
                                    {__('Recommended', 'prorank-seo')}
                                  </strong>
                                  <code style={{ fontSize: '13px', wordBreak: 'break-all' }}>
                                    {getIssueRecommendedValue(issue)}
                                  </code>
                                </div>
                              )}
                            </div>
                          )}

                          {issue.how_to_fix && (
                            <div className="prorank-audit-detail-card prorank-audit-detail-card--fix">
                              <strong className="prorank-audit-detail-card__label">
                                {__('Recommended action', 'prorank-seo')}
                              </strong>
                              <p style={{ margin: 0, color: '#1e40af' }}>{issue.how_to_fix}</p>
                            </div>
                          )}

                          <Flex gap={2} className="prorank-audit-action-row">
                            {issue.fix_available && onFixIssue && (
                              <Button 
                                variant="primary"
                                size="small"
                                onClick={() => onFixIssue(issue)}
                              >
                                {__('Apply Fix', 'prorank-seo')}
                              </Button>
                            )}
                            {onIgnoreIssue && (
                              <Button 
                                variant="secondary"
                                size="small"
                                onClick={() => onIgnoreIssue(issue)}
                              >
                                {__('Ignore', 'prorank-seo')}
                              </Button>
                            )}
                            {issue.reference && (
                              <Button 
                                variant="tertiary"
                                size="small"
                                href={issue.reference}
                                target="_blank"
                              >
                                {__('Learn More', 'prorank-seo')}
                                <Icon icon={external} size={14} style={{ marginLeft: '4px' }} />
                              </Button>
                            )}
                          </Flex>
                        </div>
                      </div>
                    )}
                  </div>
                ))}
              </CardBody>
            </Card>
          ))}
        </section>
      ))}
    </div>
  );
};

export default IssuesPage;
