import React, { useState, useEffect } from 'react';
import { useRef } from 'react';
import {
  Shield,
  Settings,
  Sliders,
  Clock,
  CheckCircle,
  AlertTriangle,
  XCircle,
  Download,
  ChevronRight,
  X,
  Calendar
} from 'lucide-react';
import Configure from './Configure';
import NoticeModal from '../NoticeModal/NoticeModal';
import { getNoticeData, getCore_file_directories, getInstalled_plugins, getInstalled_themes, getExclusion_option } from '../../Helpers';
import './scanner.scss';

const Scanner = () => {
  const sessionIdRef = useRef(null);
  const [activeTab, setActiveTab] = useState('scanner');
  const [scanInProgress, setScanInProgress] = useState(false);
  const [currentSession, setCurrentSession] = useState(null);
  const [progress, setProgress] = useState(0);
  const [progressMessage, setProgressMessage] = useState('Ready to scan');
  const [scanResults, setScanResults] = useState(null);
  const [scanHistory, setScanHistory] = useState([]);
  const [scanStats, setScanStats] = useState({
    filesProcessed: 0,
    totalFiles: 0,
    checksCompleted: 0,
    totalChecks: 0,
    currentItem: ''
  });
  const [exclusions, setExclusions] = useState({
    paths: '',
    file_patterns: '',
    php_functions: '',
    core_files: [],
    plugins: [],
    themes: []
  });

  const [directories, setDirectories] = useState([]);
  const [plugins, setPlugins] = useState([]);
  const [themes, setThemes] = useState([]);

  const [modalConfig, setModalConfig] = useState({
    isOpen: false,
    type: 'confirmation',
    title: '',
    message: '',
    onConfirm: () => { },
    confirmText: 'Confirm',
    declineText: 'Cancel'
  });

  const closeModal = () => {
    setModalConfig(prev => ({ ...prev, isOpen: false }));
  };

  const getSeverityIcon = (status) => {
    switch (status?.toLowerCase()) {
      case 'critical':
        return <XCircle size={20} className="status-icon critical" />;
      case 'vulnerable':
        return <XCircle size={20} className="status-icon vulnerable" />;
      case 'warning':
        return <AlertTriangle size={20} className="status-icon warning" />;
      case 'secure':
        return <CheckCircle size={20} className="status-icon secure" />;
      default:
        return <AlertTriangle size={20} className="status-info secure" />;
    }
  };

  const renderProgressCircle = () => {
    const radius = 60;
    const circumference = 2 * Math.PI * radius;
    const roundedProgress = Math.round(progress);
    const strokeDashoffset = circumference - (roundedProgress / 100) * circumference;

    return (
      <div className="progress-circle-container">
        <svg className="progress-ring" width="150" height="150">
          <circle
            className="progress-ring-circle-bg"
            strokeWidth="8"
            fill="transparent"
            r={radius}
            cx="75"
            cy="75"
          />
          <circle
            className="progress-ring-circle"
            strokeWidth="8"
            fill="transparent"
            r={radius}
            cx="75"
            cy="75"
            style={{
              strokeDasharray: `${circumference} ${circumference}`,
              strokeDashoffset: strokeDashoffset
            }}
          />
          <text x="75" y="75" className="progress-text">
            {roundedProgress}%
          </text>
          <text x="75" y="95" className="progress-subtext">
            Complete
          </text>
        </svg>
      </div>
    );
  };


  useEffect(() => {
    const coreDirs = getCore_file_directories();
    setDirectories(coreDirs);

    const installedPlugins = getInstalled_plugins();
    setPlugins(installedPlugins);

    const installedThemes = getInstalled_themes();
    setThemes(installedThemes);

    const savedSession = localStorage.getItem('currentSession');
    if (savedSession) {
      setCurrentSession(savedSession); // Restore from local storage
      sessionIdRef.current = savedSession; // Update ref
    }

    loadScanHistory();
    loadExclusions();
  }, []);




  // Load exclusions from the saved options
  const loadExclusions = () => {
    try {
      const savedExclusions = getExclusion_option();
      if (savedExclusions) {
        setExclusions({
          paths: Array.isArray(savedExclusions.paths) ? savedExclusions.paths.join('\n') : '',
          file_patterns: Array.isArray(savedExclusions.file_patterns) ? savedExclusions.file_patterns.join('\n') : '',
          php_functions: Array.isArray(savedExclusions.php_functions) ? savedExclusions.php_functions.join('\n') : '',
          core_files: Array.isArray(savedExclusions.core_files) ? savedExclusions.core_files : [],
          plugins: Array.isArray(savedExclusions.plugins) ? savedExclusions.plugins : [],
          themes: Array.isArray(savedExclusions.themes) ? savedExclusions.themes : []
        });
      }
    } catch (error) {
      console.error('Error loading exclusions:', error);
    }
  };

  // Render checkboxes with saved state
  const exclusionsToHide = {
    // core_files: ["core"],
    plugins: [
      "notifier-to-slack/notifier-to-slack.php",
      "notifier-to-slack-pro/notifier-to-slack-pro.php",
    ],
  };

  const renderDirectoryCheckboxes = (type, items) => {
    // Filter out items with prefix- and items in exclusionsToHide
    const filteredItems = items.filter(item => {
      const hasPrefix = item.startsWith('prefix-');
      const isExcluded = exclusionsToHide[type]?.includes(item);
      return !hasPrefix && !isExcluded;
    });

    return (
      <div className="checkbox-group">
        {filteredItems.map((item, index) => (
          <div key={index} className="checkbox-item">
            <input
              type="checkbox"
              id={`${type}-${index}`}
              name={type}
              value={item}
              checked={exclusions[type].includes(item)}
              onChange={(e) => handleDirectoryChange(type, item, e.target.checked)}
            />
            <label htmlFor={`${type}-${index}`}>{item}</label>
          </div>
        ))}
      </div>
    );
  };

  // Handler for checkbox changes
  const handleDirectoryChange = (type, item, checked) => {
    setExclusions(prev => ({
      ...prev,
      [type]: checked
        ? [...prev[type], item]
        : prev[type].filter(i => i !== item)
    }));
  };


  const makeAjaxRequest = async (action, data = {}) => {
    const formData = new FormData();
    formData.append('action', action);
    formData.append('nonce', appLocalizer.nonce);

    // Log the payload for debugging
    // console.log('Sending AJAX request with payload:', { action, ...data });

    Object.entries(data).forEach(([key, value]) => {
      if (Array.isArray(value) || typeof value === 'object') {
        formData.append(key, JSON.stringify(value));
      } else {
        formData.append(key, value);
      }
    });

    try {
      const response = await fetch(appLocalizer.admin_ajax, {
        method: 'POST',
        credentials: 'same-origin',
        body: formData,
      });

      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`);
      }

      const responseData = await response.json();
      if (responseData.success) {
        return responseData.data;
      } else {
        throw new Error(responseData.data || 'Ajax request failed');
      }
    } catch (error) {
      console.error(`Ajax error in ${action}:`, error);
      throw error;
    }
  };

  const loadScanHistory = async () => {
    try {
      const history = await makeAjaxRequest('get_scan_history');
      if (Array.isArray(history)) {
        setScanHistory(history.map(scan => ({
          ...scan,
          total_issues: countIssues(scan.issue_summary || scan?.details?.issue_summary || {})
        })));
      }
    } catch (error) {
      console.error('Error loading scan history:', error);
    }
  };

  const countIssues = (issueSummary) => {
    let totalIssues = 0;

    if (typeof issueSummary === "string") {
      try {
        issueSummary = JSON.parse(issueSummary);
      } catch (e) {
        return 0;
      }
    }

    if (typeof issueSummary === "object" && issueSummary !== null) {
      Object.values(issueSummary).forEach(count => {
        totalIssues += parseInt(count, 10) || 0;
      });
    }

    return totalIssues;
  };

  const fetchScanDetails = async (scanIndex) => {
    try {
      const data = await makeAjaxRequest('get_specific_scan_details', { scan_index: scanIndex });
      renderScanDetails(data);
    } catch (error) {
      alert('Failed to retrieve scan details');
    }
  };

  const renderScanDetails = (data) => {
    if (!data) return;

    setScanResults({
      date: data.date,
      status: data.status,
      details: renderSecuritySection(data.details)
    });
  };

  const renderSecuritySection = (details) => {
    if (!details) return null;

    return {
      core_scan: details.core_scan || {},
      security_checks: details.security_checks || {},
      wordpress_version: details.security_checks?.wordpress_version,
      plugin_vulnerabilities: details.security_checks?.plugin_vulnerabilities
    };
  };


  const startBatchedScan = async () => {
    setScanInProgress(true);
    initializeScanUI();
    try {
      await runScanPhase('initialize');
    } catch (error) {
      handleScanError(error.message);
    }
  };

  const initializeScanUI = () => {
    setProgress(0);
    setProgressMessage('Initializing Scan...');
    setScanResults(null);
    setScanStats({
      filesProcessed: 0,
      totalFiles: 0,
      checksCompleted: 0,
      totalChecks: 0,
      currentItem: 'Preparing scan...'
    });
  };

  useEffect(() => {
    // console.log('Current session updated:', currentSession);
  }, [currentSession]);

  const runScanPhase = async (phase) => {
    try {
      // console.log('Sending request with session_id:', sessionIdRef.current); // Debug log
      const data = await makeAjaxRequest('run_security_scan', {
        scan_type: phase,
        session_id: sessionIdRef.current, // Use ref value
      });
      await handleBatchResponse(data);
    } catch (error) {
      handleScanError('Scan failed: ' + error.message);
    }
  };



  const handleBatchResponse = async (data) => {
    if (!data) return;

    switch (data.type) {
      case 'initialize':
        // Save the session_id to state and ref
        setCurrentSession(data.session_id);
        sessionIdRef.current = data.session_id; // Store in ref
        localStorage.setItem('currentSession', data.session_id);
        // console.log('Session ID updated:', data.session_id); // Debug log

        setProgress(0);
        setProgressMessage('Starting core files scan...');
        await runScanPhase('core_files');
        break;

      case 'progress':
        setProgress(data.progress || 0);
        setProgressMessage(data.message || 'Processing...');
        updateScanProgress(data);
        break;

      case 'complete':
        completeScan(data);
        setScanResults(data);
        break;

      default:
        console.error('Unknown response type:', data.type);
    }
  };

  const updateScanProgress = async (data) => {
    setScanStats(prevStats => ({
      ...prevStats,
      filesProcessed: data.processed_files || prevStats.filesProcessed,
      totalFiles: data.total_files || prevStats.totalFiles,
      checksCompleted: data.completed_checks || prevStats.checksCompleted,
      totalChecks: data.total_checks || prevStats.totalChecks,
      currentItem: data.current_path || data.current_check || prevStats.currentItem
    }));

    if (data.phase === 'core_files' && !data.is_complete) {
      await runScanPhase('core_files');
    } else if (data.phase === 'core_files' && data.is_complete) {
      setProgress(50);
      setProgressMessage('Starting security checks...');
      await runScanPhase('security_checks');
    } else if (data.phase === 'security_checks' && !data.is_complete) {
      await runScanPhase('security_checks');
    } else if (data.phase === 'security_checks' && data.is_complete) {
      await runScanPhase('finalize');
    }
  };

  const completeScan = (data) => {
    setScanInProgress(false);
    setProgress(100);
    setProgressMessage('Scan Complete');
    if (data.results) {
      renderScanDetails(data.results);
    }
    loadScanHistory();
    localStorage.removeItem('currentSession');
  };

  const handleScanError = (message) => {
    setScanInProgress(false);
    setProgressMessage('Scan Failed');
    setScanResults({
      error: true,
      message
    });
  };

  const handleExclusionChange = (field, value) => {
    setExclusions(prev => ({
      ...prev,
      [field]: value
    }));
  };


  const handleExclusionSubmit = async (e) => {
    e.preventDefault();
    try {
      // Create FormData object
      const formData = new FormData();
      formData.append('action', 'update_scan_exclusions');
      formData.append('nonce', appLocalizer.nonce);

      // Append text areas as arrays
      formData.append('paths', exclusions.paths.split('\n').filter(Boolean).join('\n'));
      formData.append('file_patterns', exclusions.file_patterns.split('\n').filter(Boolean).join('\n'));
      formData.append('php_functions', exclusions.php_functions.split('\n').filter(Boolean).join('\n'));

      // Append directory selections as JSON strings
      formData.append('core_files', JSON.stringify(exclusions.core_files));
      formData.append('plugins', JSON.stringify(exclusions.plugins));
      formData.append('themes', JSON.stringify(exclusions.themes));

      const response = await fetch(appLocalizer.admin_ajax, {
        method: 'POST',
        credentials: 'same-origin',
        body: formData
      });

      const responseData = await response.json();
      if (responseData.success) {
        setModalConfig({
          isOpen: true,
          type: 'toast',
          title: 'success!',
          message: 'Exclusion settings saved successfully.',
          position: 'top-right'
        });
        setTimeout(closeModal, 3000);
      } else {
        throw new Error(responseData.data || 'Failed to save exclusions');
      }
    } catch (error) {
      console.error('Error saving exclusions:', error);
      setModalConfig({
        isOpen: true,
        type: 'toast',
        title: 'warning!',
        message: 'Error saving exclusion settings.',
        position: 'top-right'
      });
      setTimeout(closeModal, 3000);

    }
  };


  const formatScanResults = (data) => {
    if (!data) return "No results available.";

    // Special handler for core_scan issues
    const formatCoreScanIssues = (issues) => {
      if (!Array.isArray(issues)) return null;

      return issues.map((issue, idx) => {
        if (typeof issue === 'object' && issue !== null) {
          return (
            <li key={idx} className="scan-list-item">
              <div className="scan-item">
                <strong className="scan-label">file:</strong>
                <span className="scan-value">{issue.file}</span>
              </div>
              {issue.issues && Array.isArray(issue.issues) && (
                <div className="scan-item">
                  <strong className="scan-label">issues:</strong>
                  <ul className="scan-list">
                    {issue.issues.map((subIssue, subIdx) => (
                      <li key={subIdx} className="scan-list-item">
                        <span className="scan-value">{subIssue}</span>
                      </li>
                    ))}
                  </ul>
                </div>
              )}
            </li>
          );
        }
        return (
          <li key={idx} className="scan-list-item">
            <span className="scan-value">{issue}</span>
          </li>
        );
      });
    };

    const formatData = (obj) => {
      return Object.keys(obj).map((key, index) => {
        const value = obj[key];

        // Special handling for core_scan
        if (key === 'core_scan' && typeof value === 'object' && value !== null) {
          return (
            <div key={index} className="scan-item">
              <strong className="scan-label">{key}:</strong>
              <div className="scan-nested">
                {Object.keys(value).map((coreKey, coreIndex) => {
                  const coreValue = value[coreKey];

                  if (coreKey === 'issues' && Array.isArray(coreValue)) {
                    return (
                      <div key={coreIndex} className="scan-item">
                        <strong className="scan-label">{coreKey}:</strong>
                        <ul className="scan-list">
                          {formatCoreScanIssues(coreValue)}
                        </ul>
                      </div>
                    );
                  }

                  return formatData({ [coreKey]: coreValue })[0];
                })}
              </div>
            </div>
          );
        }

        // Handle objects
        if (typeof value === "object" && value !== null && !Array.isArray(value)) {
          return (
            <div key={index} className="scan-item">
              <strong className="scan-label">{key}:</strong>
              <div className="scan-nested">{formatData(value)}</div>
            </div>
          );
        }

        // Handle arrays
        if (Array.isArray(value)) {
          return (
            <div key={index} className="scan-item">
              <strong className="scan-label">{key}:</strong>
              <ul className="scan-list">
                {value.map((item, idx) => (
                  <li key={idx} className="scan-list-item">{formatData(item)}</li>
                ))}
              </ul>
            </div>
          );
        }

        // Handle special cases for better styling
        const getSpecialClass = () => {
          switch (key.toLowerCase()) {
            case 'type':
              return `scan-type scan-type--${value.toLowerCase()}`;
            case 'plugin':
              return 'scan-plugin-name';
            case 'version':
              return 'scan-version';
            case 'description':
              return 'scan-description';
            case 'recommendation':
              return 'scan-recommendation';
            default:
              return 'scan-value';
          }
        };

        // For primitive values
        return (
          <div key={index} className="scan-item">
            <strong className="scan-label">{key}:</strong>
            <span className={getSpecialClass()}>{value.toString()}</span>
          </div>
        );
      });
    };

    return formatData(data);
  };


  // Download scan log history 
  const downloadScanLog = async (scanDate) => {
    try {
      // const data = await makeAjaxRequest('download_scan_log', { scan_date: scanDate });
      const data = await makeAjaxRequest('download_scan_log', {
        scan_date: scanDate,
        nonce: appLocalizer.nonce
      });

      if (data && data.content) {
        // Create a blob from the log content
        const blob = new Blob([data.content], { type: 'text/plain' });

        // Create a downloadable link
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.style.display = 'none';
        a.href = url;

        // Format filename with the date
        const formattedDate = scanDate.replace(/[: ]/g, '-');
        a.download = `security-scan-${formattedDate}.txt`;

        // Trigger download
        document.body.appendChild(a);
        a.click();

        // Clean up
        window.URL.revokeObjectURL(url);
        document.body.removeChild(a);

        setModalConfig({
          isOpen: true,
          type: 'toast',
          title: 'success!',
          message: 'Scan log downloaded.',
          position: 'top-right'
        });
        setTimeout(closeModal, 3000);

      } else {
        setModalConfig({
          isOpen: true,
          type: 'toast',
          title: 'warning!',
          message: 'No log content received.',
          position: 'top-right'
        });
        setTimeout(closeModal, 3000);

        throw new Error('No log content received');
      }
    } catch (error) {
      console.error('Error downloading scan log:', error);
      setModalConfig({
        isOpen: true,
        type: 'toast',
        title: 'warning!',
        message: 'Failed to download scan log.',
        position: 'top-right'
      });
      setTimeout(closeModal, 3000);
    }
  };


  const clearScanResults = () => {
    setScanResults(null);
    setModalConfig({
      isOpen: true,
      type: 'toast',
      title: 'success!',
      message: 'Scal log clean from preview.',
      position: 'top-right'
    });
    setTimeout(closeModal, 3000);
  };

  return (
    <div className="security-dashboard">
      <div className="dashboard-header">
        <Shield size={32} />
        <h1>Security Scanner</h1>{`  `}
        <p className="NEW_TAG">New</p>
        <p className="BETA_TAG">Beta</p>
      </div>

      <div className="tabs">
        <button
          className={`tab ${activeTab === 'scanner' ? 'active' : ''}`}
          onClick={() => setActiveTab('scanner')}
        >
          <Shield size={20} />
          Scanner
        </button>
        <button
          className={`tab ${activeTab === 'settings' ? 'active' : ''}`}
          onClick={() => setActiveTab('settings')}
        >
          <Settings size={20} />
          Exclusion Settings
        </button>

        {/* configure tab   */}
        <button
          className={`tab ${activeTab === 'configure' ? 'active' : ''}`}
          onClick={() => setActiveTab('configure')}
        >
          <Sliders size={20} />
          Configure
        </button>

      </div>

      {activeTab === 'scanner' && (
        <div className="scanner-content">
          <div className="scanner-grid">
            <div className="scan-control-panel">
              <div className="scan-status-card">
                {renderProgressCircle()}
                <div className="scan-info">
                  <h3>{progressMessage}</h3>
                  {scanInProgress && (
                    <div className="scan-stats">
                      <div className="stat-item">
                        <span className="stat-label">Files:</span>
                        <span className="stat-value">
                          {scanStats.filesProcessed}/{scanStats.totalFiles}
                        </span>
                      </div>
                      <div className="stat-item">
                        <span className="stat-label">Checks:</span>
                        <span className="stat-value">
                          {scanStats.checksCompleted}/{scanStats.totalChecks}
                        </span>
                      </div>
                    </div>
                  )}
                </div>
                <button
                  className={`scan-button ${scanInProgress ? 'scanning' : ''}`}
                  onClick={startBatchedScan}
                  disabled={scanInProgress}
                >
                  {scanInProgress ? 'Scanning...' : 'Start Scan'}
                </button>
              </div>
            </div>

            <div className="scan-results-panel">
              <div className="panel-header">
                <h2>
                  <Clock size={20} />
                  Scan History
                </h2>
              </div>
              <div className="history-list">
                {scanHistory.map((scan, index) => (
                  <div key={index} className="history-item">
                    <div className="history-item-header">
                      {getSeverityIcon(scan.status)}
                      <span className="scan-date">{scan.date}</span>
                      <span className={`scan-status status-${scan.status?.toLowerCase()}`}>
                        {scan.status}
                      </span>
                      <button
                        className="view-details"
                        onClick={() => fetchScanDetails(index)}
                      >
                        View Details <ChevronRight size={16} />
                      </button>

                      <button
                        className="download-log"
                        onClick={(e) => {
                          e.stopPropagation();
                          downloadScanLog(scan.date);
                        }}
                      >
                        <Download size={16} /> Download Log
                      </button>

                    </div>
                    <div className="history-item-details">
                      <span className="issues-count">
                        Issues found: {scan.total_issues}
                      </span>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Scan Results Section */}
          <div className="scan-results-section">

            <div className="results-container">
              {scanResults?.error ? (
                <div className="scan-error">
                  <h3>Error</h3>
                  <p>{scanResults.message}</p>
                </div>
              ) : scanResults && (
                <div className="scan-results">
                  <h2>Current Scan Results</h2>

                  <button
                    className="close-results-btn"
                    onClick={clearScanResults}
                    aria-label="Close scan results"
                  >
                    <X size={18} />
                  </button>


                  <div className="results-header">
                    <div className="result-meta">
                      <span className="scan-date">Issues: {scanResults.total_issues}</span>
                      <span className={`scan-status status-${scanResults.status?.toLowerCase()}`}>
                        Status: {scanResults.status}
                      </span>
                    </div>

                    {/* Display results properly */}
                    {scanResults?.results && (
                      <span className="scan-results">
                        {formatScanResults(scanResults.results)}
                      </span>
                    )}

                    {scanResults.details && (
                      <span className="scan-results">
                        {formatScanResults(scanResults.details)}
                      </span>
                    )}
                  </div>

                </div>
              )}
            </div>
          </div>
          {/* End Scan Results Section */}
        </div>
      )}

      {activeTab === 'settings' && (
        <div className="settings-content">
          <div className="exclusion-settings">
            <h2>Scan Exclusion Settings</h2>
            <form id="exclusion-settings-form" onSubmit={handleExclusionSubmit}>
              <div className="exclusion-section">
                <h3>General Exclusions</h3>
                <div>
                  <label>Exclude Paths (one per line):</label>
                  <textarea
                    id="exclude-paths"
                    name="paths"
                    value={exclusions.paths}
                    onChange={(e) => handleExclusionChange('paths', e.target.value)}
                  />
                </div>
                <div>
                  <label>Exclude File Patterns (one per line):</label>
                  <textarea
                    id="exclude-file-patterns"
                    name="file_patterns"
                    value={exclusions.file_patterns}
                    onChange={(e) => handleExclusionChange('file_patterns', e.target.value)}
                  />
                </div>
                <div>
                  <label>Exclude PHP Functions (one per line):</label>
                  <textarea
                    id="exclude-functions"
                    name="php_functions"
                    value={exclusions.php_functions}
                    onChange={(e) => handleExclusionChange('php_functions', e.target.value)}
                  />
                </div>
              </div>

              <div className="exclusion-section">
                <h3>Exclusions</h3>

                <div>
                  <h4>Directories</h4>
                  {renderDirectoryCheckboxes('core_files', directories)}
                </div>

                <div>
                  <h4>Active Plugins</h4>
                  {renderDirectoryCheckboxes('plugins', plugins)}
                </div>

                <div>
                  <h4>Active Themes</h4>
                  {renderDirectoryCheckboxes('themes', themes)}
                </div>
              </div>

              <button type="submit" className="button button-primary">Save Exclusions</button>
            </form>
          </div>
        </div>
      )}


      {/* configure tab  */}
      {activeTab === 'configure' && <Configure />}

      <NoticeModal
        isOpen={modalConfig.isOpen}
        onClose={closeModal}
        onConfirm={modalConfig.onConfirm}
        onDecline={closeModal}
        type={modalConfig.type}
        title={modalConfig.title}
        message={modalConfig.message}
        confirmText={modalConfig.confirmText}
        declineText={modalConfig.declineText}
        position={modalConfig.position || 'center'}
        autoClose={modalConfig.type === 'toast'}
        autoCloseTime={3000}
      />

    </div>
  );
};

export default Scanner;
