import React, { useState } from 'react';
import { useSiteDesign, DEFAULT_SITE_DESIGN } from '../../state/SiteDesignContext';
import { usePages } from '../../state/PageContext';
import { useEditorConfig } from '../../state/EditorConfigContext';
import { SerializedTreeNode } from '../../types/sitesmith';
import { FONT_FAMILIES } from '../../constants/presets';
import { AssetPicker } from '../../ui/AssetPicker';
import { inputStyle } from './styles/shared';

type DesignTab = 'basic' | 'advanced';

/* ---------- Color picker with preset swatches ---------- */

const COLOR_SWATCHES = [
  '#3b82f6', '#8b5cf6', '#10b981', '#ef4444',
  '#f59e0b', '#ec4899', '#06b6d4', '#f97316',
];

const NEUTRAL_SWATCHES = [
  '#ffffff', '#f9fafb', '#e5e7eb', '#9ca3af',
  '#6b7280', '#374151', '#1f2937', '#111827',
];

interface ColorFieldProps {
  label: string;
  value: string;
  onChange: (value: string) => void;
  swatches?: string[];
}

const ColorField: React.FC<ColorFieldProps> = ({ label, value, onChange, swatches = COLOR_SWATCHES }) => (
  <div className="guided-section">
    <label className="guided-section-label">{label}</label>
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, marginBottom: 8 }}>
      <input
        type="color"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        style={{
          width: 32,
          height: 32,
          padding: 0,
          border: '2px solid var(--color-border)',
          borderRadius: 'var(--radius-sm)',
          cursor: 'pointer',
          background: 'none',
        }}
      />
      <input
        type="text"
        className="guided-input"
        value={value}
        onChange={(e) => onChange(e.target.value)}
        style={{ flex: 1, fontSize: 11, fontFamily: 'monospace' }}
      />
    </div>
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(8, 1fr)', gap: 4 }}>
      {swatches.map((c) => (
        <button
          key={c}
          onClick={() => onChange(c)}
          style={{
            width: '100%',
            aspectRatio: '1',
            borderRadius: 'var(--radius-sm)',
            border: value === c ? '2px solid var(--color-accent)' : '2px solid var(--color-border)',
            background: c,
            cursor: 'pointer',
            boxShadow: value === c ? '0 0 0 2px var(--color-accent)' : 'none',
            transition: 'border-color 0.15s, box-shadow 0.15s',
          }}
          title={c}
        />
      ))}
    </div>
  </div>
);

/* ---------- Font dropdown ---------- */

interface FontFieldProps {
  label: string;
  value: string;
  onChange: (value: string) => void;
}

const FontField: React.FC<FontFieldProps> = ({ label, value, onChange }) => (
  <div className="guided-section">
    <label className="guided-section-label">{label}</label>
    <select
      className="control-select"
      value={value}
      onChange={(e) => onChange(e.target.value)}
      style={{ fontSize: 12 }}
    >
      {FONT_FAMILIES.map((f) => (
        <option key={f.value} value={f.value} style={{ fontFamily: f.value }}>
          {f.label}
        </option>
      ))}
    </select>
  </div>
);

/* ---------- Border radius presets ---------- */

const BORDER_RADIUS_PRESETS = [
  { label: '0', value: '0' },
  { label: '4px', value: '4px' },
  { label: '8px', value: '8px' },
  { label: '12px', value: '12px' },
  { label: '16px', value: '16px' },
];

interface RadiusFieldProps {
  label: string;
  value: string;
  onChange: (value: string) => void;
}

const RadiusField: React.FC<RadiusFieldProps> = ({ label, value, onChange }) => (
  <div className="guided-section">
    <label className="guided-section-label">{label}</label>
    <div className="preset-grid" style={{ gridTemplateColumns: 'repeat(5, 1fr)' }}>
      {BORDER_RADIUS_PRESETS.map((p) => (
        <button
          key={p.value}
          className={`preset-btn ${value === p.value ? 'active' : ''}`}
          onClick={() => onChange(p.value)}
        >
          {p.label}
        </button>
      ))}
    </div>
  </div>
);

/* ---------- Nav style toggle ---------- */

interface NavStyleFieldProps {
  value: 'light' | 'dark';
  onChange: (value: 'light' | 'dark') => void;
}

const NavStyleField: React.FC<NavStyleFieldProps> = ({ value, onChange }) => (
  <div className="guided-section">
    <label className="guided-section-label">Nav Style</label>
    <div style={{ display: 'flex', gap: 6 }}>
      {(['light', 'dark'] as const).map((s) => (
        <button
          key={s}
          className={`preset-btn ${value === s ? 'active' : ''}`}
          style={{ flex: 1, textTransform: 'capitalize' }}
          onClick={() => onChange(s)}
        >
          {s === 'light' ? 'Light' : 'Dark'}
        </button>
      ))}
    </div>
  </div>
);

/* ---------- Reset Entire Site (danger zone) ---------- */

// Blank replacement trees for the "Reset Entire Site" escape hatch. Shaped
// as a `SerializedTreeNode` (type + props + nodes), NOT a flat Craft.js
// state entry -- this is what `replaceAllPages`/`setHeader`/`setFooter`
// feed into `treeToCraftState` -> `sanitizeAiTree`/`flattenTreeForCraft`
// (see `state/PageContext.tsx`/`utils/craft-tree.ts`). A single `Container`
// root with no children mirrors the (unexported) EMPTY_CANVAS/EMPTY_HEADER/
// EMPTY_FOOTER constants already used elsewhere for "blank".
const BLANK_PAGE_TREE: SerializedTreeNode = {
  type: { resolvedName: 'Container' },
  props: { style: { minHeight: '100vh', backgroundColor: '#ffffff' }, tag: 'div' },
  nodes: [],
};

const BLANK_HEADER_TREE: SerializedTreeNode = {
  type: { resolvedName: 'Container' },
  props: {
    style: { minHeight: '60px', backgroundColor: '#ffffff', padding: '12px 24px', display: 'flex', alignItems: 'center' },
    tag: 'header',
  },
  nodes: [],
};

const BLANK_FOOTER_TREE: SerializedTreeNode = {
  type: { resolvedName: 'Container' },
  props: {
    style: { minHeight: '60px', backgroundColor: '#0f172a', color: '#94a3b8', padding: '40px 24px', textAlign: 'center' },
    tag: 'footer',
  },
  nodes: [],
};

/**
 * Single source of truth for "has the user typed enough to arm the confirm
 * button" -- used for the `disabled` attribute/cursor/opacity AND, more
 * importantly, inside `handleResetSite` itself. `disabled` is a UI
 * affordance, not a safety mechanism (it only stops a plain mouse click);
 * for the one action in this app that irreversibly wipes a user's whole
 * site draft, the real guard has to live in the handler, checked against
 * this exact same predicate rather than a second hand-rolled comparison
 * that could drift out of sync with it.
 *
 * An empty/falsy `domain` always returns `false`, even if `typed` is also
 * empty -- `''.trim() === ''.trim()` would otherwise "match" trivially.
 * Standalone mode (no `WHP_CONFIG`) has `siteDomain === ''`, and while the
 * entry point that would let a user reach this code is hidden in that case
 * (see the `siteDomain &&` guard around the whole danger zone below), this
 * function must not depend on that -- it has to fail safe on its own if
 * ever reached with no configured domain.
 *
 * Exported so it's directly unit-testable without needing a way to render
 * the (deliberately unreachable-when-`siteDomain`-is-empty) confirm UI.
 */
export function siteResetConfirmMatches(typed: string, domain: string): boolean {
  return !!domain && typed.trim() === domain.trim();
}

/* ---------- Main SiteDesignPanel ---------- */

export const SiteDesignPanel: React.FC = () => {
  const { design, updateDesign, resetToDefaults } = useSiteDesign();
  const { replaceAllPages, setHeader, setFooter } = usePages();
  const { whpConfig } = useEditorConfig();
  // Standalone mode (no WHP_CONFIG) has no site domain to confirm against --
  // an empty typed input would then trivially "match" an empty siteDomain,
  // arming the destructive confirm button with no guard at all. The entry
  // point itself is hidden in that case (see the `siteDomain &&` guard below).
  const siteDomain = whpConfig?.siteDomain ?? '';
  const [siteResetOpen, setSiteResetOpen] = useState(false);
  const [siteResetTyped, setSiteResetTyped] = useState('');
  const [tab, setTab] = useState<DesignTab>('basic');

  const handleResetSite = (): void => {
    // Load-bearing guard -- see `siteResetConfirmMatches`'s docstring. Not
    // just a UI nicety: this must hold even if the confirm button's
    // `disabled` attribute were ever bypassed (a synthetic click, or a
    // future refactor that drops it).
    if (!siteResetConfirmMatches(siteResetTyped, siteDomain)) return;

    replaceAllPages([{ name: 'Home', tree: BLANK_PAGE_TREE }]);
    setHeader(BLANK_HEADER_TREE);
    setFooter(BLANK_FOOTER_TREE);
    resetToDefaults();
    setSiteResetOpen(false);
    setSiteResetTyped('');
  };

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
      {/* Header */}
      <div style={{ marginBottom: 16, display: 'flex', alignItems: 'center', gap: 8 }}>
        <i className="fa fa-paint-brush" style={{ color: 'var(--color-accent)', fontSize: 14 }} />
        <span style={{ fontSize: 13, fontWeight: 600, color: 'var(--color-text)' }}>
          Site Design Tokens
        </span>
      </div>

      {/* Tab switcher */}
      <div style={{ display: 'flex', gap: 4, marginBottom: 16 }}>
        {(['basic', 'advanced'] as DesignTab[]).map((t) => (
          <button
            key={t}
            onClick={() => setTab(t)}
            style={{
              flex: 1,
              padding: '6px 12px',
              fontSize: 11,
              fontWeight: 600,
              textTransform: 'uppercase',
              letterSpacing: '0.5px',
              color: tab === t ? '#fff' : 'var(--color-text-muted)',
              background: tab === t ? 'var(--color-accent)' : 'var(--color-bg-elevated)',
              border: tab === t ? '1px solid var(--color-accent)' : '1px solid var(--color-border)',
              borderRadius: 'var(--radius-sm)',
              cursor: 'pointer',
              transition: 'all 0.15s ease',
            }}
          >
            {t}
          </button>
        ))}
      </div>

      {/* Basic tab */}
      {tab === 'basic' && (
        <>
          <div className="guided-section">
            <label className="guided-section-label">Favicon</label>
            <AssetPicker
              value={design.favicon}
              onChange={(url) => updateDesign({ favicon: url })}
              mediaType="image"
              variant="full"
              placeholder="Or paste favicon URL..."
            />
            <p style={{ fontSize: 10, color: 'var(--color-text-dim)', margin: '4px 0 0' }}>
              Shown in browser tabs and bookmarks. Applies site-wide.
            </p>
          </div>
          <ColorField
            label="Primary Color"
            value={design.primaryColor}
            onChange={(v) => updateDesign({ primaryColor: v })}
          />
          <ColorField
            label="Secondary Color"
            value={design.secondaryColor}
            onChange={(v) => updateDesign({ secondaryColor: v })}
          />
          <ColorField
            label="Accent Color"
            value={design.accentColor}
            onChange={(v) => updateDesign({ accentColor: v })}
          />
          <FontField
            label="Heading Font"
            value={design.headingFont}
            onChange={(v) => updateDesign({ headingFont: v })}
          />
          <FontField
            label="Body Font"
            value={design.bodyFont}
            onChange={(v) => updateDesign({ bodyFont: v })}
          />
          <ColorField
            label="Link Color"
            value={design.linkColor}
            onChange={(v) => updateDesign({ linkColor: v })}
          />
        </>
      )}

      {/* Advanced tab */}
      {tab === 'advanced' && (
        <>
          <ColorField
            label="Primary Color"
            value={design.primaryColor}
            onChange={(v) => updateDesign({ primaryColor: v })}
          />
          <ColorField
            label="Secondary Color"
            value={design.secondaryColor}
            onChange={(v) => updateDesign({ secondaryColor: v })}
          />
          <ColorField
            label="Accent Color"
            value={design.accentColor}
            onChange={(v) => updateDesign({ accentColor: v })}
          />
          <ColorField
            label="Success Color"
            value={design.successColor}
            onChange={(v) => updateDesign({ successColor: v })}
          />
          <ColorField
            label="Warning Color"
            value={design.warningColor}
            onChange={(v) => updateDesign({ warningColor: v })}
          />
          <ColorField
            label="Error Color"
            value={design.errorColor}
            onChange={(v) => updateDesign({ errorColor: v })}
          />
          <ColorField
            label="Background Color"
            value={design.backgroundColor}
            onChange={(v) => updateDesign({ backgroundColor: v })}
            swatches={NEUTRAL_SWATCHES}
          />
          <ColorField
            label="Text Color"
            value={design.textColor}
            onChange={(v) => updateDesign({ textColor: v })}
            swatches={NEUTRAL_SWATCHES}
          />
          <ColorField
            label="Muted Text Color"
            value={design.mutedTextColor}
            onChange={(v) => updateDesign({ mutedTextColor: v })}
            swatches={NEUTRAL_SWATCHES}
          />
          <ColorField
            label="Border Color"
            value={design.borderColor}
            onChange={(v) => updateDesign({ borderColor: v })}
            swatches={NEUTRAL_SWATCHES}
          />
          <FontField
            label="Heading Font"
            value={design.headingFont}
            onChange={(v) => updateDesign({ headingFont: v })}
          />
          <FontField
            label="Body Font"
            value={design.bodyFont}
            onChange={(v) => updateDesign({ bodyFont: v })}
          />
          <FontField
            label="Button Font"
            value={design.buttonFont}
            onChange={(v) => updateDesign({ buttonFont: v })}
          />
          <ColorField
            label="Link Color"
            value={design.linkColor}
            onChange={(v) => updateDesign({ linkColor: v })}
          />
          <RadiusField
            label="Default Border Radius"
            value={design.borderRadius}
            onChange={(v) => updateDesign({ borderRadius: v })}
          />
          <RadiusField
            label="Button Radius"
            value={design.buttonRadius}
            onChange={(v) => updateDesign({ buttonRadius: v })}
          />
          <NavStyleField
            value={design.navStyle}
            onChange={(v) => updateDesign({ navStyle: v })}
          />
        </>
      )}

      {/* Reset button */}
      <div style={{ marginTop: 16, paddingTop: 12, borderTop: '1px solid var(--color-border)' }}>
        <button
          onClick={resetToDefaults}
          style={{
            width: '100%',
            padding: '8px 12px',
            fontSize: 11,
            fontWeight: 600,
            color: 'var(--color-text-muted)',
            background: 'var(--color-bg-elevated)',
            border: '1px solid var(--color-border)',
            borderRadius: 'var(--radius-sm)',
            cursor: 'pointer',
            transition: 'all 0.15s ease',
          }}
        >
          Reset to Defaults
        </button>
        <p style={{
          fontSize: 10,
          color: 'var(--color-text-dim)',
          textAlign: 'center',
          margin: '8px 0 0',
          lineHeight: 1.4,
        }}>
          Design tokens are saved with your project and applied to new components.
        </p>
      </div>

      {/* Reset Entire Site (danger zone) -- hidden entirely in standalone
          mode, where siteDomain is '' and typing nothing would trivially
          satisfy an empty-string match. */}
      {siteDomain && (
        <div
          style={{
            marginTop: 18, padding: 12,
            border: '1px solid rgba(239,68,68,0.35)',
            borderRadius: 'var(--radius-sm)',
            background: 'rgba(239,68,68,0.06)',
          }}
        >
          <div style={{ fontSize: 11, fontWeight: 700, color: '#ef4444', textTransform: 'uppercase', letterSpacing: '0.5px', marginBottom: 6 }}>
            Danger zone
          </div>

          {!siteResetOpen ? (
            <button
              data-action="open-site-reset"
              onClick={() => setSiteResetOpen(true)}
              style={{
                width: '100%', padding: '8px 12px', fontSize: 11, fontWeight: 600,
                color: '#ef4444', background: 'transparent',
                border: '1px solid rgba(239,68,68,0.5)', borderRadius: 'var(--radius-sm)', cursor: 'pointer',
              }}
            >
              Reset Entire Site
            </button>
          ) : (
            <>
              <p style={{ fontSize: 11, color: 'var(--color-text-muted)', lineHeight: 1.5, margin: '0 0 8px' }}>
                This blanks <strong>every page</strong>, the header, the footer, all
                design tokens (colors, fonts, radii), and your custom head code and
                favicon, leaving one empty Home page. Uploaded images are kept.
                <strong> This cannot be undone.</strong> Your published site stays as it
                is until you publish again — but the editor auto-saves roughly every 30
                seconds, so the blank version becomes your saved draft shortly after.
              </p>
              <p style={{ fontSize: 11, color: 'var(--color-text-muted)', margin: '0 0 4px' }}>
                Type <code>{siteDomain}</code> to confirm:
              </p>
              <input
                data-testid="site-reset-domain"
                value={siteResetTyped}
                onChange={(e) => setSiteResetTyped(e.target.value)}
                placeholder={siteDomain}
                style={inputStyle}
              />
              <div style={{ display: 'flex', gap: 6, marginTop: 8 }}>
                <button
                  data-action="confirm-site-reset"
                  disabled={!siteResetConfirmMatches(siteResetTyped, siteDomain)}
                  onClick={handleResetSite}
                  style={{
                    flex: 1, padding: '7px 10px', fontSize: 11, fontWeight: 600,
                    color: '#fff', background: '#ef4444', border: 'none',
                    borderRadius: 'var(--radius-sm)',
                    cursor: siteResetConfirmMatches(siteResetTyped, siteDomain) ? 'pointer' : 'not-allowed',
                    opacity: siteResetConfirmMatches(siteResetTyped, siteDomain) ? 1 : 0.5,
                  }}
                >
                  Reset everything
                </button>
                <button
                  onClick={() => { setSiteResetOpen(false); setSiteResetTyped(''); }}
                  style={{
                    flex: 1, padding: '7px 10px', fontSize: 11, fontWeight: 600,
                    color: 'var(--color-text-muted)', background: 'var(--color-bg-elevated)',
                    border: '1px solid var(--color-border)', borderRadius: 'var(--radius-sm)', cursor: 'pointer',
                  }}
                >
                  Cancel
                </button>
              </div>
            </>
          )}
        </div>
      )}

    </div>
  );
};
