/**
 * Settings Lint Hook
 *
 * Provides real-time validation and warnings for settings.
 *
 * @package
 * @since   0.1.0
 */

import { useState, useEffect, useCallback } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
 * Validation rule types
 */
const RULE_TYPES = {
  WARNING: 'warning',
  ERROR: 'error',
  INFO: 'info',
};

/**
 * Default validation rules
 */
const DEFAULT_RULES = [
  // Sitemap rules
  {
    id: 'sitemap-max-entries-performance',
    type: RULE_TYPES.WARNING,
    fields: ['posts_per_sitemap', 'include_images'],
    validate: (values) => {
      const maxEntries = parseInt(values.posts_per_sitemap) ?? 1000;
      const includeImages = values.include_images;

      if (maxEntries > 5000 && includeImages === true) {
        return {
          field: 'posts_per_sitemap',
          message: __(
            'High number of entries with images enabled may cause performance issues. Consider reducing entries or disabling images.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },
  {
    id: 'sitemap-max-entries-limit',
    type: RULE_TYPES.ERROR,
    fields: ['posts_per_sitemap'],
    validate: (values) => {
      const maxEntries = parseInt(values.posts_per_sitemap) ?? 1000;

      if (maxEntries > 50000) {
        return {
          field: 'posts_per_sitemap',
          message: __(
            'Maximum entries cannot exceed 50,000 per sitemap as per XML sitemap protocol.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },

  // Meta title/description rules
  {
    id: 'meta-title-length',
    type: RULE_TYPES.WARNING,
    fields: ['default_title_template'],
    validate: (values) => {
      const template = values.default_title_template ?? '';
      // Rough estimate assuming average replacements
      const estimatedLength = template.replace(/{[^}]+}/g, 'Example Text').length;

      if (estimatedLength > 60) {
        return {
          field: 'default_title_template',
          message: __(
            'Title template may generate titles longer than 60 characters. Search engines may truncate longer titles.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },
  {
    id: 'meta-description-length',
    type: RULE_TYPES.WARNING,
    fields: ['default_description_template'],
    validate: (values) => {
      const template = values.default_description_template ?? '';
      // Rough estimate assuming average replacements
      const estimatedLength = template.replace(/{[^}]+}/g, 'Example Text for Description').length;

      if (estimatedLength > 160) {
        return {
          field: 'default_description_template',
          message: __(
            'Description template may generate descriptions longer than 160 characters. Search engines may truncate longer descriptions.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },

  // Redirect rules
  {
    id: 'redirect-chain-prevention',
    type: RULE_TYPES.WARNING,
    fields: ['enable_auto_redirects', 'max_redirect_chain'],
    validate: (values) => {
      const autoRedirects = values.enable_auto_redirects;
      const maxChain = parseInt(values.max_redirect_chain) ?? 3;

      if (autoRedirects === true && maxChain > 5) {
        return {
          field: 'max_redirect_chain',
          message: __(
            'Allowing long redirect chains can impact page load performance and SEO. Consider keeping this value at 3 or less.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },

  // Schema markup rules
  {
    id: 'schema-organization-required',
    type: RULE_TYPES.INFO,
    fields: ['enable_schema_markup', 'organization_name'],
    validate: (values) => {
      const schemaEnabled = values.enable_schema_markup;
      const orgName = values.organization_name;

      if (schemaEnabled === true && (orgName === null || orgName === undefined || orgName === '')) {
        return {
          field: 'organization_name',
          message: __(
            'Organization name is recommended when schema markup is enabled for better structured data.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },

  // Performance rules
  {
    id: 'lazy-loading-conflict',
    type: RULE_TYPES.WARNING,
    fields: ['enable_lazy_loading', 'lazy_load_threshold'],
    validate: (values) => {
      const lazyLoading = values.enable_lazy_loading;
      const threshold = parseInt(values.lazy_load_threshold) ?? 0;

      if (lazyLoading === true && threshold < 0) {
        return {
          field: 'lazy_load_threshold',
          message: __(
            'Negative threshold values may cause images to never load. Use 0 or positive values.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },

  // Robots.txt rules
  {
    id: 'robots-crawl-delay',
    type: RULE_TYPES.WARNING,
    fields: ['robots_crawl_delay'],
    validate: (values) => {
      const crawlDelay = parseInt(values.robots_crawl_delay) ?? 0;

      if (crawlDelay > 10) {
        return {
          field: 'robots_crawl_delay',
          message: __(
            'High crawl delay values may prevent search engines from properly indexing your site. Consider values under 10 seconds.',
            'prorank-seo'
          ),
        };
      }
      return null;
    },
  },
];

/**
 * Settings Lint Hook
 *
 * @param {Object} settings    Current settings values
 * @param {Array } customRules Additional validation rules
 * @return {Object} Lint results with validation state and methods
 */
export const useSettingsLint = (settings = {}, customRules = []) => {
  const [validationResults, setValidationResults] = useState({});
  const [isValidating, setIsValidating] = useState(false);

  /**
   * Run validation rules
   *
   * @return {void}
   */
  const runValidation = useCallback(() => {
    setIsValidating(true);
    const results = {};

    // Combine default and custom rules
    const allRules = [...DEFAULT_RULES, ...customRules];

    allRules.forEach((rule) => {
      // Check if all required fields for this rule exist in settings
      const relevantValues = {};
      let hasAllFields = true;

      rule.fields.forEach((field) => {
        if (field in settings) {
          relevantValues[field] = settings[field];
        } else {
          hasAllFields = false;
        }
      });

      // Only run validation if we have all required fields
      if (hasAllFields) {
        const result = rule.validate(relevantValues);
        if (result !== null && result !== undefined) {
          results[result.field] = results[result.field] ?? [];
          results[result.field].push({
            id: rule.id,
            type: rule.type,
            message: result.message,
          });
        }
      }
    });

    setValidationResults(results);
    setIsValidating(false);
  }, [settings, customRules]);

  // Run validation when settings change
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      runValidation();
    }, 500); // Debounce validation

    return () => clearTimeout(timeoutId);
  }, [runValidation]);

  /**
   * Get validation messages for a specific field
   *
   * @param {string} fieldName Field name
   * @return {Array} Validation messages
   */
  const getFieldMessages = useCallback(
    (fieldName) => {
      return validationResults[fieldName] ?? [];
    },
    [validationResults]
  );

  /**
   * Check if a field has errors
   *
   * @param {string} fieldName Field name
   * @return {boolean} Has errors
   */
  const hasErrors = useCallback(
    (fieldName) => {
      const messages = getFieldMessages(fieldName);
      return messages.some((msg) => msg.type === RULE_TYPES.ERROR);
    },
    [getFieldMessages]
  );

  /**
   * Check if a field has warnings
   *
   * @param {string} fieldName Field name
   * @return {boolean} Has warnings
   */
  const hasWarnings = useCallback(
    (fieldName) => {
      const messages = getFieldMessages(fieldName);
      return messages.some((msg) => msg.type === RULE_TYPES.WARNING);
    },
    [getFieldMessages]
  );

  /**
   * Get all validation messages
   *
   * @return {Array} All messages
   */
  const getAllMessages = useCallback(() => {
    const allMessages = [];
    Object.entries(validationResults).forEach(([field, messages]) => {
      messages.forEach((msg) => {
        allMessages.push({
          ...msg,
          field,
        });
      });
    });
    return allMessages;
  }, [validationResults]);

  /**
   * Clear validation for a specific field
   *
   * @param {string} fieldName Field name
   * @return {void}
   */
  const clearFieldValidation = useCallback((fieldName) => {
    setValidationResults((prev) => {
      const newResults = { ...prev };
      delete newResults[fieldName];
      return newResults;
    });
  }, []);

  /**
   * Add custom validation result
   *
   * @param {string} fieldName  Field name
   * @param {Object} validation Validation result
   * @return {void}
   */
  const addValidation = useCallback((fieldName, validation) => {
    setValidationResults((prev) => ({
      ...prev,
      [fieldName]: [...(prev[fieldName] ?? []), validation],
    }));
  }, []);

  return {
    validationResults,
    isValidating,
    getFieldMessages,
    hasErrors,
    hasWarnings,
    getAllMessages,
    clearFieldValidation,
    addValidation,
    runValidation,
    RULE_TYPES,
  };
};

export default useSettingsLint;
