import { useEffect, useState } from '@wordpress/element';
import { __ } from '@wordpress/i18n';
import { TextareaControl, TextControl } from '@wordpress/components';
import apiFetch from '@wordpress/api-fetch';
import { Alert, Button, Card, Toggle } from '../../../components/ui';
import { useNotification } from '../../../contexts/NotificationContext';
import FontDeliveryHealthPanel from './FontDeliveryHealthPanel';
import * as React from 'react';

interface AssetSettings {
  js_minify_enabled: boolean;
  js_minify_inline: boolean;
  minify_html: boolean;
  remove_html_comments: boolean;
  host_google_fonts_locally: boolean;
  font_display_swap: boolean;
  optm_skip_roles: string[];
  content_visibility_enabled: boolean;
  content_visibility_selectors: string;
  content_visibility_size_hint: string;
}

interface AssetOptimizationSettingsProps {
  onClose?: () => void;
  embedded?: boolean;
}

const DEFAULT_SETTINGS: AssetSettings = {
  js_minify_enabled: false,
  js_minify_inline: false,
  minify_html: false,
  remove_html_comments: true,
  host_google_fonts_locally: false,
  font_display_swap: false,
  optm_skip_roles: [],
  content_visibility_enabled: false,
  content_visibility_selectors: '',
  content_visibility_size_hint: 'auto 800px',
};

const normalizeBooleanSetting = (value: unknown): boolean => {
  if (typeof value === 'boolean') {
    return value;
  }
  if (typeof value === 'number') {
    return value !== 0;
  }
  if (typeof value === 'string') {
    const normalized = value.trim().toLowerCase();
    if (['1', 'true', 'yes', 'on', 'enabled'].includes(normalized)) {
      return true;
    }
    if (['0', 'false', 'no', 'off', 'disabled', ''].includes(normalized)) {
      return false;
    }
  }
  return Boolean(value);
};

const normalizeStringList = (value: unknown): string[] => {
  if (Array.isArray(value)) {
    return value.map((item) => String(item).trim()).filter(Boolean);
  }
  if (typeof value === 'string') {
    return value.split(/[\r\n,]+/).map((item) => item.trim()).filter(Boolean);
  }
  return [];
};

const normalizeAssetSettings = (value: Partial<AssetSettings>): Partial<AssetSettings> => {
  const jsMinifyEnabled = value.js_minify_enabled ?? (value as any).js_minify;

  return {
    ...value,
    js_minify_enabled: normalizeBooleanSetting(jsMinifyEnabled),
    js_minify_inline: normalizeBooleanSetting(value.js_minify_inline),
    minify_html: normalizeBooleanSetting(value.minify_html),
    remove_html_comments: normalizeBooleanSetting(value.remove_html_comments),
    host_google_fonts_locally: normalizeBooleanSetting(value.host_google_fonts_locally),
    font_display_swap: normalizeBooleanSetting(value.font_display_swap),
    optm_skip_roles: normalizeStringList(value.optm_skip_roles),
    content_visibility_enabled: normalizeBooleanSetting(value.content_visibility_enabled),
    content_visibility_selectors: typeof value.content_visibility_selectors === 'string' ? value.content_visibility_selectors : '',
    content_visibility_size_hint: typeof value.content_visibility_size_hint === 'string' && value.content_visibility_size_hint.trim()
      ? value.content_visibility_size_hint
      : 'auto 800px',
  };
};

const toggleRowClass = 'pr:px-5 pr:py-4 pr:rounded-lg pr:border pr:border-gray-200 pr:bg-white pr:shadow-xs';

const AssetOptimizationSettings: React.FC<AssetOptimizationSettingsProps> = () => {
  const [settings, setSettings] = useState<AssetSettings>(DEFAULT_SETTINGS);
  const [loading, setLoading] = useState<boolean>(true);
  const [saving, setSaving] = useState<boolean>(false);
  const [notice, setNotice] = useState<{ type: 'success' | 'error' | 'info'; message: string } | null>(null);
  const { showNotification } = useNotification();

  useEffect(() => {
    const loadSettings = async () => {
      setLoading(true);
      try {
        const response = await apiFetch<{ settings?: Partial<AssetSettings> }>({
          path: '/prorank-seo/v1/performance/asset-settings',
        });
        setSettings({
          ...DEFAULT_SETTINGS,
          ...normalizeAssetSettings({
            ...DEFAULT_SETTINGS,
            ...(response?.settings || {}),
          }),
        });
      } catch (error: any) {
        const message = error?.message || __('Failed to load asset optimisation settings.', 'prorank-seo');
        setNotice({ type: 'error', message });
      } finally {
        setLoading(false);
      }
    };

    loadSettings();
  }, []);

  const updateSetting = <K extends keyof AssetSettings>(key: K, value: AssetSettings[K]) => {
    setSettings((prev) => ({ ...prev, [key]: value }));
  };

  const saveSettings = async () => {
    setSaving(true);
    setNotice(null);

    try {
      const normalizedSettings = normalizeAssetSettings(settings) as AssetSettings;
      await apiFetch({
        path: '/prorank-seo/v1/performance/asset-settings',
        method: 'POST',
        data: { settings: normalizedSettings },
      });
      setSettings(normalizedSettings);

      setNotice({ type: 'success', message: __('Asset optimisation settings saved.', 'prorank-seo') });
      showNotification(__('Asset optimisation settings saved.', 'prorank-seo'), 'success');
    } catch (error: any) {
      const message = error?.message || __('Failed to save asset optimisation settings.', 'prorank-seo');
      setNotice({ type: 'error', message });
      showNotification(message, 'error');
    } finally {
      setSaving(false);
    }
  };

  if (loading) {
    return <div className="pr:p-6 pr:text-sm pr:text-gray-600">{__('Loading asset optimisation settings…', 'prorank-seo')}</div>;
  }

  return (
    <div className="pr:space-y-6 pr:max-w-5xl">
      {notice && <Alert variant={notice.type} title={notice.message} />}

      <Card>
        <div className="pr:space-y-4">
          <h3 className="pr:text-lg pr:font-semibold pr:text-gray-900">{__('JavaScript Minification', 'prorank-seo')}</h3>
          <p className="pr:text-sm pr:text-gray-600">
            {__('Compress front-end JavaScript files to reduce transfer size. Keep these off if another performance plugin already minifies or rewrites JavaScript output.', 'prorank-seo')}
          </p>
          <Toggle
            className={toggleRowClass}
            label={__('Minify JavaScript files', 'prorank-seo')}
            checked={settings.js_minify_enabled}
            onChange={(value: boolean) => updateSetting('js_minify_enabled', value)}
          />
          <Toggle
            className={toggleRowClass}
            label={__('Minify inline JavaScript', 'prorank-seo')}
            checked={settings.js_minify_inline}
            onChange={(value: boolean) => updateSetting('js_minify_inline', value)}
            description={__('Enable this only if your site outputs a lot of inline script blocks and no other optimizer is already touching final HTML/script output.', 'prorank-seo')}
          />
        </div>
      </Card>

      <Card>
        <div className="pr:space-y-4">
          <h3 className="pr:text-lg pr:font-semibold pr:text-gray-900">{__('HTML Optimisation', 'prorank-seo')}</h3>
          <p className="pr:text-sm pr:text-gray-600">
            {__('Trim page output by minifying HTML and removing comments where safe. Avoid stacking these with another plugin that already rewrites final HTML.', 'prorank-seo')}
          </p>
          <Toggle
            className={toggleRowClass}
            label={__('Minify HTML output', 'prorank-seo')}
            checked={settings.minify_html}
            onChange={(value: boolean) => updateSetting('minify_html', value)}
          />
          <Toggle
            className={toggleRowClass}
            label={__('Remove HTML comments', 'prorank-seo')}
            checked={settings.remove_html_comments}
            onChange={(value: boolean) => updateSetting('remove_html_comments', value)}
          />
        </div>
      </Card>

      <Card>
        <div className="pr:space-y-4">
          <h3 className="pr:text-lg pr:font-semibold pr:text-gray-900">{__('Font Optimisation', 'prorank-seo')}</h3>
          <p className="pr:text-sm pr:text-gray-600">
            {__('Host Google Fonts locally and add font-display=swap to improve rendering stability and reduce third-party requests.', 'prorank-seo')}
          </p>
          <Toggle
            className={toggleRowClass}
            label={__('Host Google Fonts locally', 'prorank-seo')}
            checked={settings.host_google_fonts_locally}
            onChange={(value: boolean) => updateSetting('host_google_fonts_locally', value)}
          />
          <Toggle
            className={toggleRowClass}
            label={__('Force font-display: swap', 'prorank-seo')}
            checked={settings.font_display_swap}
            onChange={(value: boolean) => updateSetting('font_display_swap', value)}
          />
        </div>
      </Card>

      {/* Read-only Font Delivery Health (reuses get_stats; no toggles) */}
      <FontDeliveryHealthPanel />

      <Card>
        <div className="pr:space-y-4">
          <h3 className="pr:text-lg pr:font-semibold pr:text-gray-900">{__('Role-Based Optimisation Skip', 'prorank-seo')}</h3>
          <p className="pr:text-sm pr:text-gray-600">
            {__('Skip CSS and JavaScript rewriting for logged-in users with selected roles. Useful for editors, shop managers, and support staff using dynamic admin bars or front-end tooling.', 'prorank-seo')}
          </p>
          <TextareaControl
            __nextHasNoMarginBottom
            label={__('Skipped Roles', 'prorank-seo')}
            help={__('One role slug per line, for example administrator, editor, or shop_manager.', 'prorank-seo')}
            value={settings.optm_skip_roles.join('\n')}
            onChange={(value) => updateSetting('optm_skip_roles', normalizeStringList(value))}
            rows={4}
            placeholder="administrator&#10;editor&#10;shop_manager"
          />
        </div>
      </Card>

      <Card>
        <div className="pr:space-y-4">
          <h3 className="pr:text-lg pr:font-semibold pr:text-gray-900">{__('Content Visibility', 'prorank-seo')}</h3>
          <p className="pr:text-sm pr:text-gray-600">
            {__('Apply content-visibility:auto to selected below-fold containers so the browser can skip rendering off-screen sections until needed.', 'prorank-seo')}
          </p>
          <Toggle
            className={toggleRowClass}
            label={__('Enable content-visibility:auto', 'prorank-seo')}
            checked={settings.content_visibility_enabled}
            onChange={(value: boolean) => updateSetting('content_visibility_enabled', value)}
          />
          {settings.content_visibility_enabled && (
            <>
              <TextareaControl
                __nextHasNoMarginBottom
                label={__('Selectors', 'prorank-seo')}
                help={__('One safe CSS selector per line. Use below-fold wrappers only, not headers, hero sections, or checkout controls.', 'prorank-seo')}
                value={settings.content_visibility_selectors}
                onChange={(value) => updateSetting('content_visibility_selectors', value)}
                rows={4}
                placeholder=".site-main section:nth-of-type(n+3)&#10;.below-fold"
              />
              <TextControl
                __next40pxDefaultSize
                __nextHasNoMarginBottom
                label={__('Intrinsic Size Hint', 'prorank-seo')}
                help={__('CSS contain-intrinsic-size value used before the section renders.', 'prorank-seo')}
                value={settings.content_visibility_size_hint}
                onChange={(value) => updateSetting('content_visibility_size_hint', value)}
                placeholder="auto 800px"
              />
            </>
          )}
        </div>
      </Card>

      <Card>
        <div className="pr:space-y-3">
          <h3 className="pr:text-lg pr:font-semibold pr:text-gray-900">{__('Automatic Free Runtime Optimisations', 'prorank-seo')}</h3>
          <ul className="pr:list-disc pr:pl-5 pr:space-y-2 pr:text-sm pr:text-gray-600">
            <li>{__('CLS prevention is handled by the free Performance runtime when the Performance module is enabled.', 'prorank-seo')}</li>
            <li>{__('Core Web Vitals beacon collection is handled automatically by the free Performance runtime when its monitoring modules are enabled.', 'prorank-seo')}</li>
            <li>{__('Advanced Critical CSS, Unused CSS removal, script isolation, and video optimisation are not part of the free build.', 'prorank-seo')}</li>
          </ul>
        </div>
      </Card>

      <div className="pr:flex pr:gap-3">
        <Button variant="primary" onClick={saveSettings} disabled={saving}>
          {saving ? __('Saving…', 'prorank-seo') : __('Save Settings', 'prorank-seo')}
        </Button>
      </div>
    </div>
  );
};

export default AssetOptimizationSettings;
