import React, { useState, useEffect, useCallback, memo } from 'react';
import { useAdmin } from '../../context/AdminContext';

// ── Constants ──

const CHANNEL_META = {
  google_ads: { label: 'Google Ads', color: '#4285F4' },
  meta:       { label: 'Meta Ads',   color: '#0668E1' },
  tiktok:     { label: 'TikTok Ads', color: '#010101' },
};

const FACTOR_META = {
  age_skew: {
    label: 'Age Skew',
    icon: '👤',
    description: 'Adjusts channel mix based on audience age profile',
    values: {
      young:  { label: 'Young (18–34)', icon: '🎯' },
      mature: { label: 'Mature (45+)',  icon: '🏛️' },
    },
  },
  market_scope: {
    label: 'Market Scope',
    icon: '📍',
    description: 'Adjusts channel mix based on geographic targeting scope',
    values: {
      local:    { label: 'Local',    icon: '🏘️' },
      regional: { label: 'Regional', icon: '🗺️' },
      national: { label: 'National', icon: '🌐' },
    },
  },
};

const fmt = (s) => (s || '').replace(/_/g, ' ').replace(/\b\w/g, c => c.toUpperCase());

// ── Main Panel ──

export default function ModifiersPanel() {
  const { apiCall } = useAdmin();
  const [modifiers, setModifiers] = useState([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);
  const [saving, setSaving] = useState(null);
  const [dirty, setDirty] = useState({});
  const [toast, setToast] = useState(null);

  // Preview state
  const [previewCategory, setPreviewCategory] = useState('restaurant');
  const [previewObjective, setPreviewObjective] = useState('awareness');
  const [previewAgeSkew, setPreviewAgeSkew] = useState('young');
  const [previewMarketScope, setPreviewMarketScope] = useState('local');
  const [previewResult, setPreviewResult] = useState(null);
  const [previewLoading, setPreviewLoading] = useState(false);

  // Toast auto-dismiss
  useEffect(() => {
    if (!toast) return;
    const t = setTimeout(() => setToast(null), 3000);
    return () => clearTimeout(t);
  }, [toast]);

  // Load modifiers
  const loadModifiers = useCallback(async () => {
    setLoading(true);
    setError(null);
    const res = await apiCall('/api/admin/modifiers');
    if (res.ok) {
      setModifiers(res.modifiers || []);
    } else {
      setError(res.error || 'Failed to load modifiers');
    }
    setLoading(false);
  }, [apiCall]);

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

  // Track local edits
  const updateLocal = (id, field, value) => {
    setDirty(prev => ({
      ...prev,
      [id]: { ...(prev[id] || {}), [field]: value }
    }));
  };

  // Get effective value (dirty or original)
  const getVal = (mod, field) => {
    return dirty[mod.id]?.[field] !== undefined ? dirty[mod.id][field] : mod[field];
  };

  // Save a single modifier
  const saveMod = async (mod) => {
    const changes = dirty[mod.id];
    if (!changes) return;

    setSaving(mod.id);
    const res = await apiCall(`/api/admin/modifiers/${mod.id}`, 'PUT', changes);
    if (res.ok) {
      setModifiers(prev => prev.map(m =>
        m.id === mod.id ? { ...m, ...changes } : m
      ));
      setDirty(prev => {
        const next = { ...prev };
        delete next[mod.id];
        return next;
      });
      setToast('Modifier saved');
    } else {
      setError(res.error || 'Save failed');
    }
    setSaving(null);
  };

  // Save all dirty modifiers in a group
  const saveGroup = async (mods) => {
    for (const m of mods) {
      if (dirty[m.id]) await saveMod(m);
    }
  };

  // Preview recommendation
  const runPreview = async () => {
    setPreviewLoading(true);
    const res = await apiCall('/api/admin/modifiers/preview', 'POST', {
      businessCategory: previewCategory,
      objective: previewObjective,
      ageSkew: previewAgeSkew || null,
      marketScope: previewMarketScope || null,
    });
    if (res.ok) {
      setPreviewResult(res);
    } else {
      setPreviewResult({ warning: res.error || 'Preview failed' });
    }
    setPreviewLoading(false);
  };

  // Group modifiers by factorType → factorValue
  const grouped = {};
  modifiers.forEach(mod => {
    const key = mod.factorType;
    if (!grouped[key]) grouped[key] = {};
    const subKey = mod.factorValue;
    if (!grouped[key][subKey]) grouped[key][subKey] = [];
    grouped[key][subKey].push(mod);
  });

  const hasDirtyCount = Object.keys(dirty).length;

  if (loading) {
    return (
      <div style={{ padding: 40, textAlign: 'center', color: '#888' }}>
        <div className="spinner"></div>
        <p>Loading modifiers…</p>
      </div>
    );
  }

  return (
    <div className="modifiers-panel">
      {/* Toast */}
      {toast && <div className="mod-toast">{toast}</div>}

      {error && (
        <div className="error-message" style={{ margin: '0 0 16px 0' }}>
          <strong>Error:</strong> {error}
          <button onClick={() => setError(null)} className="mod-dismiss-btn">✕</button>
        </div>
      )}

      <div className="mod-intro">
        <p>
          Audience modifiers adjust the base allocation template percentages based on the target audience's
          age profile and geographic scope. Positive values increase a channel's share; negative values decrease it.
          Results are normalized to 100% at recommendation time.
        </p>
        {hasDirtyCount > 0 && (
          <span className="mod-dirty-badge">{hasDirtyCount} unsaved change{hasDirtyCount !== 1 ? 's' : ''}</span>
        )}
      </div>

      {/* ── Factor Groups ── */}
      {Object.entries(FACTOR_META).map(([factorType, meta]) => (
        <div key={factorType} className="mod-group">
          <div className="mod-group-header">
            <span className="mod-group-icon">{meta.icon}</span>
            <div>
              <h3 className="mod-group-title">{meta.label}</h3>
              <p className="mod-group-desc">{meta.description}</p>
            </div>
          </div>

          {Object.entries(meta.values).map(([factorValue, valueMeta]) => {
            const mods = grouped[factorType]?.[factorValue] || [];
            const groupDirty = mods.some(m => dirty[m.id]);

            return (
              <div key={factorValue} className="mod-value-section">
                <div className="mod-value-header">
                  <span className="mod-value-icon">{valueMeta.icon}</span>
                  <span className="mod-value-label">{valueMeta.label}</span>
                  {groupDirty && (
                    <button
                      className="mod-save-group-btn"
                      onClick={() => saveGroup(mods)}
                      disabled={saving !== null}
                    >
                      {saving ? 'Saving…' : 'Save Changes'}
                    </button>
                  )}
                </div>

                <div className="mod-slider-list">
                  {mods.map(mod => (
                    <ModifierRow
                      key={mod.id}
                      mod={mod}
                      pctAdj={getVal(mod, 'pctAdjustment')}
                      rationale={getVal(mod, 'rationale')}
                      isActive={getVal(mod, 'isActive')}
                      isDirty={!!dirty[mod.id]}
                      isSaving={saving === mod.id}
                      onChangePct={(v) => updateLocal(mod.id, 'pctAdjustment', v)}
                      onChangeRationale={(v) => updateLocal(mod.id, 'rationale', v)}
                      onToggleActive={() => updateLocal(mod.id, 'isActive', !getVal(mod, 'isActive'))}
                      onSave={() => saveMod(mod)}
                    />
                  ))}
                  {mods.length === 0 && (
                    <div className="mod-empty">No modifiers configured for {valueMeta.label}</div>
                  )}
                </div>
              </div>
            );
          })}
        </div>
      ))}

      {/* ── Preview Section ── */}
      <div className="mod-group" style={{ marginTop: 24 }}>
        <div className="mod-group-header">
          <span className="mod-group-icon">🧪</span>
          <div>
            <h3 className="mod-group-title">Preview Recommendation</h3>
            <p className="mod-group-desc">Test how modifiers affect the channel mix for a given scenario</p>
          </div>
        </div>
        <div className="mod-preview-controls">
          <div className="mod-preview-field">
            <label>Category</label>
            <input value={previewCategory} onChange={e => setPreviewCategory(e.target.value)} placeholder="restaurant" />
          </div>
          <div className="mod-preview-field">
            <label>Objective</label>
            <input value={previewObjective} onChange={e => setPreviewObjective(e.target.value)} placeholder="awareness" />
          </div>
          <div className="mod-preview-field">
            <label>Age Skew</label>
            <select value={previewAgeSkew} onChange={e => setPreviewAgeSkew(e.target.value)}>
              <option value="">None</option>
              <option value="young">Young</option>
              <option value="mature">Mature</option>
            </select>
          </div>
          <div className="mod-preview-field">
            <label>Market Scope</label>
            <select value={previewMarketScope} onChange={e => setPreviewMarketScope(e.target.value)}>
              <option value="">None</option>
              <option value="local">Local</option>
              <option value="regional">Regional</option>
              <option value="national">National</option>
            </select>
          </div>
          <button className="mod-preview-btn" onClick={runPreview} disabled={previewLoading}>
            {previewLoading ? 'Running…' : 'Run Preview'}
          </button>
        </div>

        {previewResult && (
          <div className="mod-preview-result">
            {previewResult.warning && !previewResult.channels && (
              <div style={{ color: '#b45309', fontSize: 13, padding: '8px 0' }}>⚠ {previewResult.warning}</div>
            )}
            {previewResult.channels && (
              <div className="mod-preview-channels">
                <div className="mod-preview-row mod-preview-header-row">
                  <span className="mod-preview-ch-dot-spacer" />
                  <span className="mod-preview-ch-name" style={{ fontWeight: 600, fontSize: 11, textTransform: 'uppercase', color: '#64748b' }}>Channel</span>
                  <span className="mod-preview-ch-val" style={{ fontWeight: 600, fontSize: 11, textTransform: 'uppercase', color: '#64748b' }}>Base</span>
                  <span className="mod-preview-ch-arrow" />
                  <span className="mod-preview-ch-val" style={{ fontWeight: 600, fontSize: 11, textTransform: 'uppercase', color: '#64748b' }}>Adjusted</span>
                  <span className="mod-preview-ch-diff-spacer" />
                </div>
                {previewResult.channels.map((ch, i) => {
                  const meta = CHANNEL_META[ch.channelType] || {};
                  const diff = ch.recommendedPct - ch.basePct;
                  return (
                    <div key={i} className="mod-preview-row">
                      <span className="mod-preview-ch-dot" style={{ background: meta.color || '#999' }} />
                      <span className="mod-preview-ch-name">{meta.label || fmt(ch.channelType)}</span>
                      <span className="mod-preview-ch-val">{ch.basePct}%</span>
                      <span className="mod-preview-ch-arrow">→</span>
                      <span className="mod-preview-ch-val" style={{ fontWeight: 700 }}>{ch.recommendedPct}%</span>
                      {diff !== 0 ? (
                        <span className={`mod-preview-ch-diff ${diff > 0 ? 'pos' : 'neg'}`}>
                          {diff > 0 ? '+' : ''}{diff}
                        </span>
                      ) : (
                        <span className="mod-preview-ch-diff-spacer" />
                      )}
                    </div>
                  );
                })}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}


// ── Modifier Row with Slider ──

const ModifierRow = memo(function ModifierRow({
  mod, pctAdj, rationale, isActive, isDirty, isSaving,
  onChangePct, onChangeRationale, onToggleActive, onSave,
}) {
  const meta = CHANNEL_META[mod.channelType] || {};
  const isPositive = pctAdj > 0;
  const isNegative = pctAdj < 0;

  return (
    <div className={`mod-row ${!isActive ? 'mod-row-disabled' : ''} ${isDirty ? 'mod-row-dirty' : ''}`}>
      <div className="mod-row-top">
        <span className="mod-ch-dot" style={{ background: meta.color || '#999' }} />
        <span className="mod-ch-name">{meta.label || fmt(mod.channelType)}</span>

        <div className="mod-slider-wrap">
          <span className="mod-slider-tick mod-slider-tick-neg">-30</span>
          <input
            type="range"
            min={-30}
            max={30}
            value={pctAdj}
            onChange={e => onChangePct(parseInt(e.target.value))}
            className="mod-slider"
            style={{
              '--slider-color': isPositive ? '#10b981' : isNegative ? '#ef4444' : '#94a3b8',
            }}
          />
          <span className="mod-slider-tick mod-slider-tick-pos">+30</span>
        </div>

        <span className={`mod-pct-badge ${isPositive ? 'pos' : isNegative ? 'neg' : ''}`}>
          {pctAdj > 0 ? '+' : ''}{pctAdj}%
        </span>

        <label className="mod-toggle" title={isActive ? 'Active' : 'Disabled'}>
          <input type="checkbox" checked={isActive} onChange={onToggleActive} />
          <span className="mod-toggle-track" />
        </label>

        {isDirty && (
          <button className="mod-save-btn" onClick={onSave} disabled={isSaving} title="Save">
            {isSaving ? '…' : '✓'}
          </button>
        )}
      </div>

      <div className="mod-row-bottom">
        <input
          className="mod-rationale"
          value={rationale || ''}
          onChange={e => onChangeRationale(e.target.value)}
          placeholder="Rationale…"
          maxLength={200}
        />
      </div>
    </div>
  );
});
