// Develop panel — Lightroom-style sliders, wired to /api/edit backend

const DEV_SECTIONS = [
  { id: 'light', label: 'Light', sliders: [
    { key: 'exposure', label: 'Exposure', min: -5, max: 5, step: 0.05 },
    { key: 'contrast', label: 'Contrast', min: -100, max: 100, step: 1 },
    { key: 'highlights', label: 'Highlights', min: -100, max: 100, step: 1 },
    { key: 'shadows', label: 'Shadows', min: -100, max: 100, step: 1 },
    { key: 'whites', label: 'Whites', min: -100, max: 100, step: 1 },
    { key: 'blacks', label: 'Blacks', min: -100, max: 100, step: 1 },
  ]},
  { id: 'color', label: 'Color', sliders: [
    { key: 'temperature', label: 'Temp', min: -100, max: 100, step: 1 },
    { key: 'tint', label: 'Tint', min: -100, max: 100, step: 1 },
    { key: 'vibrance', label: 'Vibrance', min: -100, max: 100, step: 1 },
    { key: 'saturation', label: 'Saturation', min: -100, max: 100, step: 1 },
  ]},
  { id: 'detail', label: 'Detail', sliders: [
    { key: 'sharpness', label: 'Sharpness', min: 0, max: 100, step: 1 },
    { key: 'noise', label: 'Noise Reduction', min: 0, max: 100, step: 1 },
    { key: 'clarity', label: 'Clarity', min: -100, max: 100, step: 1 },
  ]},
];

const PRESETS = {
  'None':       {},
  'Portra 400': { exposure: 0.3, contrast: -10, highlights: -20, shadows: 15, temperature: 15, saturation: 10, vibrance: 15 },
  'Neutral':    { contrast: -5, highlights: -10, shadows: 5 },
  'Moody':      { exposure: -0.4, contrast: 20, highlights: -30, shadows: -20, saturation: -15, temperature: -10 },
  'B&W':        { saturation: -100, contrast: 15, clarity: 20 },
  'Flash':      { exposure: 0.6, contrast: -15, highlights: -40, temperature: -5, vibrance: 20 },
};

const XMP_FIELD_MAP = {
  Exposure2012: 'exposure', Contrast2012: 'contrast',
  Highlights2012: 'highlights', Shadows2012: 'shadows',
  Whites2012: 'whites', Blacks2012: 'blacks',
  Tint: 'tint', Vibrance: 'vibrance', Saturation: 'saturation',
  Clarity2012: 'clarity', Sharpness: 'sharpness',
};

function parseXMPPreset(text) {
  const parser = new DOMParser();
  const doc = parser.parseFromString(text, 'text/xml');
  const desc = doc.querySelector('Description');
  if (!desc) return null;

  const vals = {};
  for (const [xmpKey, sliderKey] of Object.entries(XMP_FIELD_MAP)) {
    const raw = desc.getAttribute(`crs:${xmpKey}`);
    if (raw != null) {
      const n = parseFloat(raw);
      if (!isNaN(n)) vals[sliderKey] = n;
    }
  }

  // Temperature: XMP stores absolute Kelvin; map to -100..100 around 5500K neutral
  const rawTemp = desc.getAttribute('crs:Temperature');
  if (rawTemp != null) {
    const k = parseFloat(rawTemp);
    if (!isNaN(k)) vals.temperature = Math.max(-100, Math.min(100, (k - 5500) / 30));
  }

  const nameEl = desc.getAttribute('crs:PresetName') || desc.getAttribute('crs:Name') || null;
  return { name: nameEl, vals };
}

function DevelopPanel({ open, filename, edits, onChange, onReset, onResetAll, onSave, onApplyToAll, setOpen }) {
  const [openSections, setOpenSections] = React.useState({ light: true, color: true, detail: false });
  const [preset, setPreset] = React.useState('None');
  const [saving, setSaving] = React.useState(false);
  const [saved, setSaved] = React.useState(false);
  const [customPresets, setCustomPresets] = React.useState({});
  const fileInputRef = React.useRef(null);

  const allPresets = { ...PRESETS, ...customPresets };

  const applyPreset = (name) => {
    setPreset(name);
    onResetAll();
    const vals = allPresets[name] || {};
    Object.entries(vals).forEach(([k, v]) => onChange(k, v));
  };

  const handleXMPUpload = (e) => {
    const file = e.target.files[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (ev) => {
      const result = parseXMPPreset(ev.target.result);
      if (!result || !Object.keys(result.vals).length) {
        alert('Could not read preset — make sure it is a valid Lightroom .xmp file.');
        return;
      }
      const name = result.name || file.name.replace(/\.[^.]+$/, '');
      setCustomPresets(prev => ({ ...prev, [name]: result.vals }));
      setPreset(name);
      onResetAll();
      Object.entries(result.vals).forEach(([k, v]) => onChange(k, v));
    };
    reader.readAsText(file);
    e.target.value = '';
  };

  const handleSave = async () => {
    setSaving(true);
    await onSave();
    setSaving(false);
    setSaved(true);
    setTimeout(() => setSaved(false), 1500);
  };

  const handleExport = async () => {
    if (!filename) return;
    try {
      const r = await fetch(`/api/edit/${encodeURIComponent(filename)}/export`, { method: 'POST' });
      if (!r.ok) return;
      const blob = await r.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `edit_${filename.replace(/\.[^.]+$/, '')}.jpg`;
      a.click();
      URL.revokeObjectURL(url);
    } catch {}
  };

  return (
    <aside style={{
      position: 'fixed', top: 44, right: 0, bottom: 50, width: 280, zIndex: 101,
      background: 'var(--bg-1)', borderLeft: '1px solid var(--line-1)',
      transform: open ? 'translateX(0)' : 'translateX(100%)',
      transition: 'transform 220ms cubic-bezier(0.3,0.9,0.3,1)',
      display: 'flex', flexDirection: 'column',
      boxShadow: open ? '-12px 0 40px rgba(0,0,0,0.5)' : 'none',
    }}>
      <div style={{ padding: '14px 16px', borderBottom: '1px solid var(--line-1)', display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        <div>
          <div className="mono" style={{ fontSize: 9.5, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: 0.12 }}>Non-destructive</div>
          <div className="serif" style={{ fontSize: 20, color: 'var(--ink-0)', letterSpacing: -0.3, marginTop: 2 }}>Develop</div>
        </div>
        <Btn size="sm" onClick={() => setOpen(false)} icon={<IconX size={13}/>}/>
      </div>

      {/* Presets */}
      <div style={{ padding: '10px 12px', borderBottom: '1px solid var(--line-1)' }}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 6 }}>
          <div className="mono" style={{ fontSize: 9, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: 0.14 }}>Preset</div>
          <button onClick={() => fileInputRef.current && fileInputRef.current.click()} style={{
            padding: '2px 7px', fontSize: 9.5, letterSpacing: 0.02,
            background: 'var(--bg-2)', color: 'var(--ink-2)',
            border: '1px solid var(--line-2)', borderRadius: 4, cursor: 'pointer',
          }}>+ Upload .xmp</button>
          <input ref={fileInputRef} type="file" accept=".xmp,.lrtemplate" style={{ display: 'none' }} onChange={handleXMPUpload}/>
        </div>
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 4 }}>
          {Object.keys(allPresets).map(p => (
            <button key={p} onClick={() => applyPreset(p)} style={{
              padding: '5px 4px', fontSize: 10.5, letterSpacing: 0.02,
              background: preset === p ? 'var(--bg-4)' : 'var(--bg-2)',
              color: preset === p ? 'var(--ink-0)' : 'var(--ink-2)',
              border: `1px solid ${preset === p ? 'var(--line-3)' : 'var(--line-1)'}`,
              borderRadius: 4, cursor: 'pointer', overflow: 'hidden',
              whiteSpace: 'nowrap', textOverflow: 'ellipsis',
            }} title={p}>{p}</button>
          ))}
        </div>
      </div>

      {/* Sliders */}
      <div style={{ flex: 1, overflowY: 'auto' }}>
        {DEV_SECTIONS.map(section => (
          <div key={section.id}>
            <button onClick={() => setOpenSections(s => ({ ...s, [section.id]: !s[section.id] }))}
              style={{
                width: '100%', display: 'flex', alignItems: 'center', justifyContent: 'space-between',
                padding: '10px 14px', background: 'transparent', border: 'none',
                borderBottom: '1px solid var(--line-1)', cursor: 'pointer',
                color: 'var(--ink-2)', fontFamily: 'var(--mono)',
                fontSize: 10, textTransform: 'uppercase', letterSpacing: 0.14,
              }}>
              <span>{section.label}</span>
              <IconChevD size={11} style={{ transform: openSections[section.id] ? 'none' : 'rotate(-90deg)', transition: 'transform 180ms' }}/>
            </button>
            {openSections[section.id] && (
              <div style={{ padding: '6px 14px 10px' }}>
                {section.sliders.map(s => (
                  <Slider key={s.key} {...s} value={edits[s.key] || 0}
                    onChange={v => onChange(s.key, v)}
                    onDblClick={() => onReset(s.key)}/>
                ))}
              </div>
            )}
          </div>
        ))}
      </div>

      {/* Footer actions */}
      <div style={{ padding: '10px 12px', borderTop: '1px solid var(--line-1)', display: 'flex', flexDirection: 'column', gap: 6 }}>
        <div style={{ display: 'flex', gap: 6 }}>
          <Btn size="sm" variant="outline" onClick={onResetAll} style={{ flex: 1 }}>Reset</Btn>
          <Btn size="sm" variant="outline" onClick={handleExport} style={{ flex: 1 }}>Export</Btn>
          <Btn size="sm" variant="solid" onClick={handleSave} disabled={saving} style={{ flex: 1 }}>
            {saving ? '…' : saved ? '✓ Saved' : 'Save'}
          </Btn>
        </div>
        <div className="mono" style={{ fontSize: 9, color: 'var(--ink-3)', textAlign: 'center' }}>
          Double-click any slider to reset it
        </div>
      </div>
    </aside>
  );
}

function Slider({ label, min, max, step, value, onChange, onDblClick }) {
  const isZero = value === 0 || value === undefined;
  const pct = ((value - min) / (max - min)) * 100;
  const zeroPct = ((0 - min) / (max - min)) * 100;
  return (
    <div style={{ display: 'flex', alignItems: 'center', gap: 8, minHeight: 24, padding: '3px 0' }}>
      <span style={{ width: 70, fontSize: 11, color: 'var(--ink-2)' }}>{label}</span>
      <div style={{ flex: 1, position: 'relative', height: 16, display: 'flex', alignItems: 'center' }}>
        <div style={{ position: 'absolute', left: 0, right: 0, height: 2, background: 'var(--bg-3)', borderRadius: 1 }}/>
        <div style={{ position: 'absolute', left: `${zeroPct}%`, top: 4, bottom: 4, width: 1, background: 'var(--line-3)' }}/>
        <div style={{
          position: 'absolute', height: 2, background: 'var(--ink-1)', borderRadius: 1,
          left: `${Math.min(pct, zeroPct)}%`, width: `${Math.abs(pct - zeroPct)}%`,
        }}/>
        <input type="range" min={min} max={max} step={step} value={value||0}
          onChange={e => onChange(parseFloat(e.target.value))}
          onDoubleClick={onDblClick}
          style={{ position: 'absolute', inset: 0, width: '100%', opacity: 0, cursor: 'pointer', margin: 0 }}/>
        <div style={{
          position: 'absolute', left: `calc(${pct}% - 5px)`,
          width: 10, height: 10, borderRadius: '50%',
          background: 'var(--ink-0)', boxShadow: '0 1px 3px rgba(0,0,0,0.6)',
          pointerEvents: 'none',
        }}/>
      </div>
      <span className="mono" style={{
        width: 34, textAlign: 'right', fontSize: 10.5,
        color: isZero ? 'var(--ink-3)' : 'var(--ink-0)',
      }}>
        {isZero ? '0' : (value > 0 ? '+' : '') + (step < 1 ? value.toFixed(2) : Math.round(value))}
      </span>
    </div>
  );
}

Object.assign(window, { DevelopPanel });
