import React, { useEffect, useMemo, useState } from 'react';
import WM from '@megaads/wm';
import Preview from './Preview.jsx';
import OptionsPanel from './OptionsPanel.jsx';
import { sampleMinimal, sampleMultiArtwork } from './samples.js';

const TABS = [
  { id: 'preview', label: 'Preview' },
  { id: 'config', label: 'Config payload' },
  { id: 'state', label: 'State' },
  { id: 'snapshot', label: 'Snapshot' },
];

export default function App() {
  const [campaignText, setCampaignText] = useState('');
  const [campaign, setCampaign] = useState(null);
  const [service, setService] = useState(null);
  const [snapshot, setSnapshot] = useState(null);
  const [tab, setTab] = useState('preview');
  const [error, setError] = useState(null);
  const [fetchInput, setFetchInput] = useState('2638329004');
  const [fetching, setFetching] = useState(false);

  useEffect(() => {
    if (!campaign) {
      setService(null);
      setSnapshot(null);
      return;
    }
    try {
      const s = WM.initCustomizationTeeinblue(campaign);
      setService(s);
      setSnapshot(s.getSnapshot());
      setError(null);
    } catch (e) {
      console.error(e);
      setError(String(e?.message || e));
      setService(null);
      setSnapshot(null);
    }
  }, [campaign]);

  const loadSample = (data) => {
    setCampaign(data);
    setCampaignText(JSON.stringify(data, null, 2));
  };

  const loadFromPaste = () => {
    try {
      const data = JSON.parse(campaignText);
      setCampaign(data);
      setError(null);
    } catch (e) {
      setError('Invalid JSON: ' + e.message);
    }
  };

  const loadFile = async (file) => {
    if (!file) return;
    try {
      const text = await file.text();
      const data = JSON.parse(text);
      setCampaignText(text);
      setCampaign(data);
      setError(null);
    } catch (e) {
      setError('Invalid file: ' + e.message);
    }
  };

  const loadFromPrinterval = async () => {
    const productId = extractProductId(fetchInput);
    if (!productId) {
      setError('Không tìm thấy product_id. Nhập số ID hoặc URL chứa ?product_id=XXX');
      return;
    }
    setFetching(true);
    setError(null);
    try {
      const res = await fetch('/api/printerval/get-campaign-data?product_id=' + productId);
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const data = await res.json();
      setCampaignText(JSON.stringify(data, null, 2));
      setCampaign(data);
    } catch (e) {
      setError('Fetch failed: ' + e.message);
    } finally {
      setFetching(false);
    }
  };

  const validation = snapshot?.validation;

  return (
    <div className="app">
      <header className="header">
        <h1>WM Playground · TeeInBlue Customization</h1>
        <div className="meta">
          {snapshot && (
            <>
              {validation?.isValid ? (
                <span style={{ color: '#22c55e' }}>✓ Valid</span>
              ) : (
                <span style={{ color: '#ef4444' }}>
                  ✗ {validation.errors.length} error(s)
                </span>
              )}
              <span style={{ marginLeft: 12 }}>
                {snapshot.layerOptions.length} option(s) · {snapshot.designLayers.length} layer(s)
              </span>
            </>
          )}
        </div>
      </header>

      <aside className="panel loader">
        <div className="section">
          <h3>Load campaign</h3>
          <button className="btn" onClick={() => loadSample(sampleMinimal)}>
            Sample (1 artwork)
          </button>
          <button className="btn" onClick={() => loadSample(sampleMultiArtwork)}>
            Sample (2 artworks)
          </button>
          <button
            className="btn secondary"
            onClick={() => {
              setCampaign(null);
              setCampaignText('');
            }}
          >
            Clear
          </button>
        </div>

        <div className="section">
          <h3>Fetch từ Printerval</h3>
          <input
            type="text"
            value={fetchInput}
            onChange={(e) => setFetchInput(e.target.value)}
            placeholder="product_id hoặc URL"
            disabled={fetching}
          />
          <div style={{ marginTop: 6 }}>
            <button
              className="btn"
              onClick={loadFromPrinterval}
              disabled={fetching || !fetchInput.trim()}
            >
              {fetching ? 'Fetching…' : 'Fetch campaign'}
            </button>
          </div>
          <div style={{ fontSize: 11, color: '#64748b', marginTop: 4 }}>
            Gọi qua proxy: <code>/api/printerval/get-campaign-data?product_id=…</code>
          </div>
        </div>

        <div className="section">
          <h3>Upload JSON</h3>
          <input
            type="file"
            accept="application/json"
            onChange={(e) => loadFile(e.target.files?.[0])}
            style={{ fontSize: 12 }}
          />
        </div>

        <div className="section">
          <h3>Paste JSON</h3>
          <textarea
            value={campaignText}
            onChange={(e) => setCampaignText(e.target.value)}
            placeholder='{"result": {"campaign_products": ...}}'
            spellCheck={false}
          />
          <div style={{ marginTop: 6 }}>
            <button className="btn" onClick={loadFromPaste} disabled={!campaignText.trim()}>
              Load JSON
            </button>
          </div>
        </div>

        {error && <div className="error-box">{error}</div>}

        {snapshot && (
          <div className="section">
            <h3>State actions</h3>
            <button
              className="btn secondary"
              onClick={() => {
                const state = service.getState();
                localStorage.setItem('wm_playground_state', JSON.stringify(state));
                alert('State saved to localStorage');
              }}
            >
              Save state
            </button>
            <button
              className="btn secondary"
              onClick={() => {
                const stored = localStorage.getItem('wm_playground_state');
                if (!stored) return alert('No saved state');
                const state = JSON.parse(stored);
                const s = WM.initCustomizationTeeinblue(campaign, {
                  templateId: state.templateId,
                  state,
                });
                setService(s);
                setSnapshot(s.getSnapshot());
              }}
            >
              Restore state
            </button>
          </div>
        )}

        {snapshot && validation && !validation.isValid && (
          <div className="section">
            <h3>Validation errors</h3>
            {validation.errors.map((err, i) => (
              <div key={i} className="error-box">
                [{err.type}] {err.label || err.artworkId}: {err.message}
              </div>
            ))}
          </div>
        )}

        {snapshot && validation?.isValid && (
          <div className="section">
            <div className="success-box">All required fields are filled.</div>
          </div>
        )}
      </aside>

      <main className="preview-area">
        <div className="preview-tabs">
          {TABS.map((t) => (
            <button
              key={t.id}
              className={'tab-btn' + (tab === t.id ? ' active' : '')}
              onClick={() => setTab(t.id)}
            >
              {t.label}
            </button>
          ))}
        </div>

        {tab === 'preview' && (
          snapshot ? (
            <Preview snapshot={snapshot} />
          ) : (
            <div className="preview-canvas">
              <div className="preview-empty">Load a campaign to begin</div>
            </div>
          )
        )}

        {tab === 'config' && (
          <div style={{ padding: 16, overflow: 'auto', flex: 1 }}>
            <pre className="json">{JSON.stringify(snapshot?.config, null, 2)}</pre>
          </div>
        )}

        {tab === 'state' && (
          <div style={{ padding: 16, overflow: 'auto', flex: 1 }}>
            <pre className="json">
              {JSON.stringify(service?.getState(), null, 2)}
            </pre>
          </div>
        )}

        {tab === 'snapshot' && (
          <div style={{ padding: 16, overflow: 'auto', flex: 1 }}>
            <pre className="json">{snapshotSummary(snapshot)}</pre>
          </div>
        )}
      </main>

      <aside className="panel options">
        <OptionsPanel
          snapshot={snapshot}
          service={service}
          onSnapshot={setSnapshot}
        />
      </aside>
    </div>
  );
}

function extractProductId(input) {
  if (!input) return null;
  const trimmed = String(input).trim();
  // Pure numeric ID
  if (/^\d+$/.test(trimmed)) return trimmed;
  // URL with ?product_id=
  const match = trimmed.match(/[?&]product_id=(\d+)/);
  if (match) return match[1];
  return null;
}

function snapshotSummary(snapshot) {
  if (!snapshot) return '';
  const slim = {
    artwork: snapshot.artwork ? { id: snapshot.artwork.id, name: snapshot.artwork.name } : null,
    template: snapshot.template ? { id: snapshot.template.id, name: snapshot.template.name } : null,
    campaignMockup: snapshot.campaignMockup
      ? { id: snapshot.campaignMockup.id, width: snapshot.campaignMockup.width, height: snapshot.campaignMockup.height }
      : null,
    printAreas: snapshot.printAreas?.map((pa) => ({
      id: pa.id,
      printarea_id: pa.printarea_id,
      width: pa.width,
      height: pa.height,
      artwork: pa.artwork,
    })),
    layerOptions: snapshot.layerOptions.map((l) => ({
      id: l.id,
      form_label: l.form_label,
      input_type: l.input_type,
      value: l.value,
      show_value: l.show_value,
      required: l.required,
      form_visibility_value: l.form_visibility_value,
      items: (l.option_items || []).length,
    })),
    designLayers: snapshot.designLayers.map((l) => ({
      id: l.id,
      type: l.type,
      top: l.top,
      left: l.left,
      width: l.width,
      height: l.height,
      text: l.text,
      src: l.src,
    })),
    fonts: snapshot.fonts,
    validation: snapshot.validation,
  };
  return JSON.stringify(slim, null, 2);
}
