/* FlexiLay wp-admin (native, no iframe)
 * Uses WP core packages: wp.element, wp.components, wp.apiFetch
 */
(function () {
  var cfg = window.flexilayAdmin || {};
  var apiFetch = (window.wp && window.wp.apiFetch) ? window.wp.apiFetch : null;
  var el = (window.wp && window.wp.element) ? window.wp.element : null;
  var comps = (window.wp && window.wp.components) ? window.wp.components : null;

  if (!apiFetch || !el || !comps) return;

  // Nonce
  if (cfg.nonce && apiFetch.createNonceMiddleware) {
    apiFetch.use(apiFetch.createNonceMiddleware(cfg.nonce));
  }

  var h = el.createElement;

  function useState(initial) { return el.useState(initial); }
  function useEffect(fn, deps) { return el.useEffect(fn, deps); }

  function fetchJSON(path, opts) {
    return apiFetch(Object.assign({ path: '/flexilay/v1' + path }, opts || {}));
  }
// Error boundary to prevent blank screens and surface runtime errors
class ErrorBoundary extends el.Component {
  constructor(props){
    super(props);
    this.state = { hasError:false, error:null };
  }
  componentDidCatch(error){
    this.setState({ hasError:true, error: error ? (error.message || String(error)) : 'Unknown error' });
    try { console.error('[FlexiLay admin] render error', error); } catch(_) {}
  }
  render(){
    if (this.state.hasError){
      return h('div', null,
        h(NoticeBar, { status:'error', dismissible:false },
          'FlexiLay admin UI error: ' + this.state.error + '. Check browser console for details.'
        )
      );
    }
    return this.props.children;
  }
}

  function Card(props) {
    return h(comps.Card, { className: props.className || '' }, h(comps.CardBody, null, props.children));
  }

  function NoticeBar(props){
    return h(comps.Notice, { status: props.status || 'info', isDismissible: !!props.dismissible }, props.children);
  }

  function PageHeader(props){
    return h('div', { className: 'flexilay-header' },
      h('div', { className: 'flexilay-title' }, props.title),
      props.actions ? h('div', { className: 'flexilay-actions' }, props.actions) : null
    );
  }

  function Onboarding() {
    var _a = useState(false), loading = _a[0], setLoading = _a[1];
    var _b = useState(null), err = _b[0], setErr = _b[1];
    var _c = useState(null), status = _c[0], setStatus = _c[1];
    var _d = useState(null), pair = _d[0], setPair = _d[1];
    var _e = useState(null), settingsRes = _e[0], setSettingsRes = _e[1];
    var _f = useState({ docs: {} }), legal = _f[0], setLegal = _f[1];
    var _g = useState(false), savingLegal = _g[0], setSavingLegal = _g[1];

    // Server-fed legal routes (open in new tab; no iframes)
    var base = (cfg.apiBase || '').replace(/\/+$/,'');
    var LEGALS = [
      { id:'merchant-terms', title:'Merchant Terms of Service', desc:'How FlexiLay can be used by your business.', url: base ? (base + '/legal/merchant-terms') : '' },
      { id:'merchant-msa', title:'Merchant Service Agreement', desc:'Service scope, responsibilities, and policies.', url: base ? (base + '/legal/merchant-msa') : '' },
      { id:'privacy-policy', title:'Privacy Policy', desc:'How customer data is handled.', url: base ? (base + '/legal/privacy-policy') : '' }
    ];

    function refreshStatus(){
      setErr(null);
      return fetchJSON('/status').then(function(res){
        setStatus(res);
        return res;
      }).catch(function(e){ setErr(String(e && e.message ? e.message : e)); });
    }

    function refreshSettings(){
      return fetchJSON('/settings').then(function(res){
        setSettingsRes(res);

        if (res && res.merchantMissing) {
          setLegal({ docs: {} });
          try {
            var staleKey = 'flexilayAcceptedDocs:' + (cfg.shopDomain || '');
            if (window.localStorage) window.localStorage.removeItem(staleKey);
          } catch(_) {}
        }

        // Canonical: acceptedDocs: ["merchant-terms","merchant-msa","privacy-policy"]
        try {
          var s = res && res.settings ? res.settings : (res && res.ok && res.data && res.data.settings ? res.data.settings : null);
          if (s && Array.isArray(s.acceptedDocs)) {
            var map = {};
            s.acceptedDocs.forEach(function(id){ map[id] = true; });
            setLegal({ docs: map });
          } else if (!res || res.merchantMissing) {
            setLegal({ docs: {} });
          }
        } catch(_) {}

        return res;
      }).catch(function(e){ /* settings optional */ });
    }

    useEffect(function(){
      refreshStatus();
      refreshSettings();
    }, []);

    function doRegister(){
      setLoading(true); setErr(null);
      fetchJSON('/onboarding/register', { method: 'POST', data: {} })
        .then(function(res){ setLoading(false); setPair(res); try { var staleKey = 'flexilayAcceptedDocs:' + (cfg.shopDomain || ''); if (window.localStorage) window.localStorage.removeItem(staleKey); } catch(_) {} refreshStatus(); refreshSettings(); })
        .catch(function(e){ setLoading(false); setErr(String(e && e.message ? e.message : e)); });
    }

    function doPair(){
      setLoading(true); setErr(null);
      fetchJSON('/onboarding/pair', { method: 'POST', data: {} })
        .then(function(res){ setLoading(false); setPair(res); try { var staleKey = 'flexilayAcceptedDocs:' + (cfg.shopDomain || ''); if (window.localStorage) window.localStorage.removeItem(staleKey); } catch(_) {} refreshStatus(); refreshSettings(); })
        .catch(function(e){ setLoading(false); setErr(String(e && e.message ? e.message : e)); });
    }

    function doStripeConnect(){
      setLoading(true); setErr(null);
      fetchJSON('/stripe/connect/start')
        .then(function(res){
          setLoading(false);
          if (res && res.ok && res.url) {
            window.open(res.url, '_blank', 'noopener,noreferrer');
            return;
          }
          try { setErr('Stripe connect failed: ' + JSON.stringify(res, null, 2)); }
          catch (_) { setErr('Stripe connect failed.'); }
        })
        .catch(function(e){ setLoading(false); setErr(String(e && e.message ? e.message : e)); });
    }

    function toggleDoc(id){
      setLegal(function(prev){
        var next = { docs: Object.assign({}, (prev && prev.docs) ? prev.docs : {}) };
        next.docs[id] = !next.docs[id];
        return next;
      });
    }

    function acceptedCount(){
      var d = (legal && legal.docs) ? legal.docs : {};
      var n = 0;
      LEGALS.forEach(function(x){ if (d[x.id]) n++; });
      return n;
    }

    function savedAcceptedCount(){
      try {
        var s = settingsRes && settingsRes.settings ? settingsRes.settings : (settingsRes && settingsRes.ok && settingsRes.data && settingsRes.data.settings ? settingsRes.data.settings : null);
        return (s && Array.isArray(s.acceptedDocs)) ? s.acceptedDocs.length : 0;
      } catch(_) {
        return 0;
      }
    }

    function allAccepted(){
      return acceptedCount() === LEGALS.length;
    }

    function savedAllAccepted(){
      return savedAcceptedCount() === LEGALS.length;
    }

function saveAcceptance(){
  if (!base) {
    setErr('FlexiLay API Base URL is not configured.');
    return;
  }

  setSavingLegal(true);
  setErr(null);

  var d = (legal && legal.docs) ? legal.docs : {};
  var accepted = LEGALS.filter(function(x){ return !!d[x.id]; }).map(function(x){ return x.id; });

  if (accepted.length !== LEGALS.length) {
    setSavingLegal(false);
    setErr('All legal documents must be accepted before saving.');
    return;
  }

  var currentSettings =
    (settingsRes && settingsRes.settings)
      ? settingsRes.settings
      : (settingsRes && settingsRes.ok && settingsRes.data && settingsRes.data.settings
          ? settingsRes.data.settings
          : {});

  var mergedSettings = Object.assign({}, currentSettings, {
    acceptedDocs: accepted
  });

  function responseAcceptedCount(res){
    try {
      var s = res && res.settings ? res.settings : (res && res.ok && res.data && res.data.settings ? res.data.settings : null);
      return (s && Array.isArray(s.acceptedDocs)) ? s.acceptedDocs.length : 0;
    } catch(_) {
      return 0;
    }
  }

  fetchJSON('/settings', {
    method: 'POST',
    data: {
      settings: mergedSettings
    }
  })
    .then(function(settingsSaveRes){
      if (responseAcceptedCount(settingsSaveRes) !== LEGALS.length) {
        throw new Error('FlexiLay did not persist the legal acceptance server-side. The backend must save acceptedDocs before onboarding can complete.');
      }

      return fetchJSON('/onboarding/complete', {
        method: 'POST',
        data: {
          acceptedDocs: accepted
        }
      });
    })
    .then(function(onboardingRes){
      if (onboardingRes && onboardingRes.ok === false) {
        throw new Error(onboardingRes.error || onboardingRes.message || 'FlexiLay could not complete onboarding after legal acceptance was submitted.');
      }

      var map = {};
      accepted.forEach(function(id){ map[id] = true; });
      setLegal({ docs: map });

      return Promise.all([
        refreshSettings(),
        refreshStatus()
      ]);
    })
    .then(function(results){
      var refreshedSettings = results && results[0] ? results[0] : null;
      if (responseAcceptedCount(refreshedSettings) !== LEGALS.length) {
        throw new Error('Legal acceptance was submitted, but FlexiLay did not return the saved documents. The server still needs to persist acceptedDocs.');
      }
      setSavingLegal(false);
    })
    .catch(function(e){
      setSavingLegal(false);
      setErr(String(e && e.message ? e.message : e));
      try { console.error('Save Acceptance failed:', e); } catch(_) {}
    });
}

    function hasTruthyKey(obj, keys){
      if (!obj || typeof obj !== 'object') return false;
      for (var i = 0; i < keys.length; i++) {
        var v = obj[keys[i]];
        if (typeof v === 'boolean') return v;
        if (typeof v === 'number') return !!v;
        if (typeof v === 'string') {
          var s = v.trim().toLowerCase();
          if (s === 'true' || s === 'yes' || s === 'connected' || s === 'complete' || s === 'approved') return true;
          if (s === 'false' || s === 'no' || s === 'incomplete' || s === 'pending' || s === 'not_connected') return false;
        }
      }
      return false;
    }

    function merchantMissing(obj){
      if (!obj || typeof obj !== 'object') return false;
      var parts = [];
      ['error', 'message', 'msg', 'detail', 'details', 'raw'].forEach(function(k){
        if (obj[k] != null) parts.push(String(obj[k]));
      });
      var hay = parts.join(' | ').toLowerCase();
      return hay.indexOf('merchant not found') >= 0 || hay.indexOf('not found') >= 0;
    }

    var stripeConnected = merchantMissing(status) ? false : hasTruthyKey(status, ['stripeConnected', 'stripe_connected', 'hasStripeAccount', 'stripeAccountConnected']);
    var step1Complete = merchantMissing(status)
      ? false
      : hasTruthyKey(status, ['paired', 'isPaired', 'pairComplete', 'apiKeyPresent', 'hasApiKey', 'registered', 'localApiKeyPresent']) ||
        !!(pair && pair.ok && (pair.apiKey || pair.paired || pair.registered));
    var legalsComplete = merchantMissing(status) ? false : savedAllAccepted();
    var legalsPendingSave = !merchantMissing(status) && allAccepted() && !savedAllAccepted();
    var onboardingComplete = merchantMissing(status)
      ? false
      : (hasTruthyKey(status, ['onboardingComplete', 'onboardingCompleted', 'isOnboardingComplete']) ||
      (step1Complete && stripeConnected && legalsComplete));

    // If everything is complete, show a simplified completion screen
    if (onboardingComplete && stripeConnected && legalsComplete) {
      var baseAdmin = (window.ajaxurl ? window.ajaxurl.replace('/admin-ajax.php','') : '');
      var paymentsUrl = baseAdmin + '/admin.php?page=wc-settings&tab=checkout&from=PAYMENTS_MENU_ITEM';
      var plansUrl = baseAdmin + '/admin.php?page=flexilay-plans';

      return h('div', null,
        h(PageHeader, {
          title: 'FlexiLay Onboarding',
          actions: h(comps.Button, { isPrimary: true, isBusy: loading, disabled: loading, onClick: function(){ refreshStatus(); refreshSettings(); } }, 'Refresh')
        }),

        err ? h(NoticeBar, { status: 'error' }, err) : null,

        h(Card, null,
          h('h3', { className:'flexilay-h3' }, 'Your onboarding is complete'),
          h('p', { className:'flexilay-p' }, 'You are now ready to accept payments through your checkout.'),
          h('div', { className:'flexilay-row', style:{marginTop:12} },
            h(comps.Button, { isPrimary:true, onClick:function(){ window.location.href = paymentsUrl; } }, 'Enable payment method'),
            h(comps.Button, { isSecondary:true, onClick:function(){ window.location.href = plansUrl; } }, 'Go to Your Plans')
          ),
          h('div', { style:{height:12} }),
          h('p', { className:'flexilay-small' }, 'If you would like to read more about how FlexiLay works, head to our website.'),
          h('p', null,
            h('a', { href:'https://flexilay.com', target:'_blank', rel:'noopener noreferrer' }, 'flexilay.com')
          ),
          h('p', { className:'flexilay-small' }, 'If you need assistance, please use the chat bubble at the bottom of the page for help.')
        )
      );
    }


    function StepPill(label, ok){
      var cls = ok ? 'flexilay-pill flexilay-pill-ok' : 'flexilay-pill flexilay-pill-bad';
      return h('span', { className: cls }, label);
    }

    function StepCard(n, title, desc, ok){
      return h('div', { className:'flexilay-step-card' + (ok ? ' is-ok' : '') },
        h('div', { className:'flexilay-step-num' }, String(n)),
        h('div', { className:'flexilay-step-main' },
          h('div', { className:'flexilay-step-title' }, title),
          h('div', { className:'flexilay-step-desc' }, desc)
        ),
        ok ? h('div', { className:'flexilay-step-check' }, '✓') : null
      );
    }

    return h('div', null,
      h(PageHeader, {
        title: 'FlexiLay Onboarding',
        actions: h(comps.Button, { isPrimary: true, isBusy: loading, disabled: loading, onClick: function(){ refreshStatus(); refreshSettings(); } }, 'Refresh')
      }),

      err ? h(NoticeBar, { status: 'error' }, err) : null,

      h(Card, null,
        h('h3', { className:'flexilay-h3' }, 'Welcome — let\'s get you set up'),
        h('p', { className:'flexilay-p' }, 'Complete the steps below to enable FlexiLay in your WooCommerce checkout. You\'ll connect Stripe, accept required documents, and then you\'re ready to create test plans.' )
      ),

      h(Card, { className:'flexilay-hero' },
        h('div', { className:'flexilay-hero-top' },
          h('div', { className:'flexilay-hero-title' }, 'Setup Progress'),
          h('div', { className:'flexilay-hero-pills' },
  StepPill(onboardingComplete ? 'Onboarding Complete' : 'Onboarding Incomplete', onboardingComplete),
  StepPill(stripeConnected ? 'Stripe Connected' : 'Stripe Not Connected', stripeConnected)
)
        ),
        h('div', { className:'flexilay-steps' },
          StepCard(1, 'Register & Pair', 'Create/refresh your merchant profile in FlexiLay.', step1Complete),
          StepCard(2, 'Connect Stripe', 'Connect your Stripe account to enable payments.', stripeConnected),
          StepCard(3, 'Accept Legal Documents', 'Accept required documents to complete setup.', legalsComplete)
        )
      ),

      h('div', { className:'flexilay-grid flexilay-grid-3' },

        h(Card, null,
          h('h3', { className:'flexilay-h3' }, 'Step 1 — Register & Pair'),
          h('p', { className:'flexilay-p' }, 'Register creates/updates your merchant record. Pair returns an API key once approved.'),
          h('div', { className:'flexilay-row' },
            h(comps.Button, { isSecondary:true, isBusy:loading, disabled:loading, onClick: doRegister }, 'Register'),
            h('span', { style:{display:'inline-block', width:8} }),
            h(comps.Button, { isPrimary:true, isBusy:loading, disabled:loading, onClick: doPair }, 'Pair / Check Approval')
          ),
          pair ? h('pre', { className:'flexilay-pre' }, JSON.stringify(pair, null, 2)) : null
        ),

        h(Card, null,
          h('h3', { className:'flexilay-h3' }, 'Step 2 — Connect Stripe'),
          h('p', { className:'flexilay-p' }, 'Stripe is required to process deposits and scheduled instalments.'),
          h('div', { className:'flexilay-row' },
            h(comps.Button, { isPrimary:true, isBusy:loading, disabled:loading || !step1Complete, onClick: doStripeConnect }, stripeConnected ? 'Stripe Connected' : 'Connect Stripe')
          ),
          stripeConnected ? h(NoticeBar, { status:'success' }, 'Stripe Connected.') : h(NoticeBar, { status:'warning' }, 'Not Connected Yet.')
        ),

        h(Card, null,
          h('h3', { className:'flexilay-h3' }, 'Step 3 — Accept Legal Documents'),
          h('p', { className:'flexilay-p' }, 'Open each document, then tick Accepted.'),
          h('div', { className:'flexilay-legal-list' },
            LEGALS.map(function(d){
              return h('div', { className:'flexilay-legal-item', key:d.id },
                h('div', { className:'flexilay-legal-title' }, d.title),
                d.desc ? h('div', { className:'flexilay-small' }, d.desc) : null,
                h('div', { className:'flexilay-row', style:{marginTop:8} },
                  h(comps.Button, { isSecondary:true, disabled: !d.url, onClick:function(){ window.open(d.url, '_blank', 'noopener,noreferrer'); } }, 'View'),
                  h('span', { style:{display:'inline-block', width:8} }),
                  h('label', { className:'flexilay-check' },
                    h('input', { type:'checkbox', checked: !!(legal && legal.docs && legal.docs[d.id]), onChange:function(){ toggleDoc(d.id); } }),
                    h('span', null, 'Accepted')
                  )
                )
              );
            })
          ),
          h('div', { className:'flexilay-row', style:{marginTop:12} },
            h(comps.Button, { isPrimary:true, isBusy:savingLegal, disabled:savingLegal || !allAccepted(), onClick: saveAcceptance }, 'Save Acceptance')
          ),
          legalsComplete
            ? h(NoticeBar, { status:'success' }, 'All legal documents accepted and saved.')
            : (legalsPendingSave
              ? h(NoticeBar, { status:'warning' }, 'All documents are ticked, but you still need to click Save Acceptance to complete onboarding.')
              : h(NoticeBar, { status:'info' }, 'All documents must be accepted and saved to complete onboarding.'))
        )
      )
    );
  }

  function Overview() {
    var _a = useState(null), data = _a[0], setData = _a[1];
    var _b = useState(null), err = _b[0], setErr = _b[1];
    var _c = useState(false), loading = _c[0], setLoading = _c[1];
    var _d = useState(null), settingsRes = _d[0], setSettingsRes = _d[1];

    function load(){
      setLoading(true);
      setErr(null);
      Promise.all([fetchJSON('/status'), fetchJSON('/settings').catch(function(){ return null; })])
        .then(function(arr){ setData(arr[0]); setSettingsRes(arr[1]); setLoading(false); })
        .catch(function(e){ setErr(String(e && e.message ? e.message : e)); setLoading(false); });
    }

    useEffect(function(){ load(); }, []);

    function hasTruthyKey(obj, keys){
      if (!obj || typeof obj !== 'object') return false;
      for (var i = 0; i < keys.length; i++) {
        var v = obj[keys[i]];
        if (typeof v === 'boolean') return v;
        if (typeof v === 'number') return !!v;
        if (typeof v === 'string') {
          var s = v.trim().toLowerCase();
          if (s === 'true' || s === 'yes' || s === 'connected' || s === 'complete' || s === 'approved') return true;
          if (s === 'false' || s === 'no' || s === 'incomplete' || s === 'pending' || s === 'not_connected') return false;
        }
      }
      return false;
    }

    function acceptedDocsCount(res){
      try {
        var s = res && res.settings ? res.settings : (res && res.ok && res.data && res.data.settings ? res.data.settings : null);
        return (s && Array.isArray(s.acceptedDocs)) ? s.acceptedDocs.length : 0;
      } catch(_) {
        return 0;
      }
    }

    var merchantMissing = !!(data && data.merchantMissing);
    var stripeConnected = merchantMissing ? false : hasTruthyKey(data, ['stripeConnected', 'stripe_connected', 'hasStripeAccount', 'stripeAccountConnected']);
    var step1Complete = merchantMissing ? false : hasTruthyKey(data, ['paired', 'isPaired', 'pairComplete', 'apiKeyPresent', 'hasApiKey', 'registered', 'localApiKeyPresent']);
    var legalsComplete = merchantMissing ? false : acceptedDocsCount(settingsRes) >= 3;
    var onboardingComplete = merchantMissing ? false : (hasTruthyKey(data, ['onboardingComplete', 'onboardingCompleted', 'isOnboardingComplete']) || (step1Complete && stripeConnected && legalsComplete));

    function goOnboarding(){
      window.location.href = (window.ajaxurl ? window.ajaxurl.replace('/admin-ajax.php','') : '') + '/admin.php?page=flexilay-onboarding';
    }

    function Pill(label, ok){
      var cls = ok ? 'flexilay-pill flexilay-pill-ok' : 'flexilay-pill flexilay-pill-bad';
      return h('span', { className: cls }, label);
    }

    return h('div', null,
      h(PageHeader, {
        title: 'Welcome to FlexiLay',
        actions: h('div', null,
          h(comps.Button, { isSecondary:true, isBusy:loading, disabled:loading, onClick: load }, 'Refresh'),
          h('span', { style:{display:'inline-block', width:8} }),
          h(comps.Button, { isPrimary:true, onClick: goOnboarding, disabled: onboardingComplete }, onboardingComplete ? 'All set' : 'Finish onboarding')
        )
      }),

      h(Card, { className:'flexilay-brand-tile' },
        h('div', { className:'flexilay-brand' },
          h('img', { className:'flexilay-brand-logo', src: (cfg.pluginUrl || '') + 'assets/img/LayBy_poweredby_FlexiLay.png', alt:'LayBy powered by FlexiLay' })
        )
      ),

      err ? h(NoticeBar, { status: 'error' }, err) : null,

      h(Card, null,
        h('h3', { className:'flexilay-h3' }, 'Welcome — let\'s get you set up'),
        h('p', { className:'flexilay-p' }, 'Complete the steps below to enable FlexiLay in your WooCommerce checkout. You\'ll connect Stripe, accept required documents, and then you\'re ready to create test plans.' )
      ),

      h(Card, { className:'flexilay-hero' },
        h('div', { className:'flexilay-hero-top' },
          h('div', { className:'flexilay-hero-title' }, 'Status monitor'),
          h('div', { className:'flexilay-hero-pills' },
            Pill(onboardingComplete ? 'Onboarding Complete' : 'Onboarding Incomplete', onboardingComplete),
            Pill(stripeConnected ? 'Stripe Connected' : 'Stripe Not Connected', stripeConnected),
          )
        ),
        (!onboardingComplete)
          ? h(NoticeBar, { status:'warning' }, h('span', null, 'You are not fully set up yet. ', h('a', { href:'#', onClick:function(e){e.preventDefault(); goOnboarding();}}, 'Go to Onboarding'), ' to complete setup.'))
          : h(NoticeBar, { status:'success' }, 'You’re ready to offer FlexiLay at checkout.')
      ),

      h('div', { className:'flexilay-grid flexilay-grid-2' },
        h(Card, null,
          h('h3', { className:'flexilay-h3' }, 'How FlexiLay works for WooCommerce'),
          h('p', { className:'flexilay-p' }, 'FlexiLay lets customers choose a deposit and payment schedule (weekly, fortnightly, or monthly). FlexiLay creates a payment plan in Stripe and manages scheduled payments.'),
          h('ul', { className:'flexilay-ul' },
            h('li', null, 'Customers complete their plan setup after checkout.'),
            h('li', null, 'Payments are processed through your connected Stripe account.'),
            h('li', null, 'You can track plans, balances, and status from your FlexiLay dashboard here in WordPress.')
          ),
          h('p', { className:'flexilay-small' }, 'Tip: FlexiLay is a lay-by model — customers receive goods once the plan is fully paid.')
        ),

        h(Card, null,
          h('h3', { className:'flexilay-h3' }, 'Watch videos'),
          h('div', { className:'flexilay-video' },
            h('div', { className:'flexilay-video-title' }, 'Onboarding walkthrough'),
            h(comps.Button, {
              isPrimary:true,
              onClick:function(){
                var u = cfg.onboardingVideoUrl || '';
                if (!u) { alert('Video link not set yet. Add it in FlexiLay settings (coming).'); return; }
                window.open(u, '_blank', 'noopener,noreferrer');
              }
            }, 'Watch onboarding video')
          ),
          h('div', { className:'flexilay-video' },
            h('div', { className:'flexilay-video-title' }, 'Add FlexiLay to checkout'),
            h(comps.Button, {
              isSecondary:true,
              onClick:function(){
                var u = cfg.checkoutVideoUrl || '';
                if (!u) { alert('Video link not set yet. Add it in FlexiLay settings (coming).'); return; }
                window.open(u, '_blank', 'noopener,noreferrer');
              }
            }, 'Adding FlexiLay to your checkout')
          ),
          h('div', { className:'flexilay-divider' }),
          h('p', { className:'flexilay-small' }, 'Need help? Head to the Onboarding tab any time to re-run setup and check your connection status.')
        )
      )
    );
  }

  function Plans() {
    var _a = useState(null), res = _a[0], setRes = _a[1];
    var _b = useState(null), statusRes = _b[0], setStatusRes = _b[1];
    var _c = useState(null), err = _c[0], setErr = _c[1];
    var _d = useState(false), loading = _d[0], setLoading = _d[1];
    var _e = useState(false), acting = _e[0], setActing = _e[1];

    var _f = useState(''), q = _f[0], setQ = _f[1];
    var _g = useState('all'), filterStatus = _g[0], setFilterStatus = _g[1];

    var _h = useState(null), selected = _h[0], setSelected = _h[1];
	var _i = useState(false), createOpen = _i[0], setCreateOpen = _i[1];
    var _j = useState({ totalCents:'', customerName:'', customerEmail:'', notes:'' }), createForm = _j[0], setCreateForm = _j[1];

    function load(){
      setLoading(true); setErr(null);
      Promise.all([
        fetchJSON('/plans?limit=200'),
        fetchJSON('/status')
      ]).then(function(arr){
        setRes(arr[0]);
        setStatusRes(arr[1]);
        setLoading(false);
      }).catch(function(e){
        setErr(String(e && e.message ? e.message : e));
        setLoading(false);
      });
    }

    useEffect(function(){ load(); }, []);

    function centsToMoney(cents, currency){
      if (cents == null) return '';
      var v = Number(cents)/100;
      try {
        return new Intl.NumberFormat(undefined, { style:'currency', currency: (currency || 'AUD') }).format(v);
      } catch(_) {
        return (currency || '') + ' ' + v.toFixed(2);
      }
    }

    function fmtDate(iso){
      if (!iso) return '';
      var d = new Date(iso);
      if (isNaN(d.getTime())) return '';
      return d.toLocaleString();
    }

    function badge(label, tone){
      var cls = 'flexilay-badge';
      if (tone) cls += ' ' + tone;
      return h('span', { className: cls }, label);
    }

    function planStatusBadge(p){
      var s = String(p.status || '').toLowerCase();
      if (s === 'completed') return badge('Completed','is-ok');
      if (s === 'active') return badge('Active','is-ok');
      if (s === 'overdue') return badge('Overdue','is-bad');
      if (s === 'cancelled') return badge('Cancelled','is-muted');
      if (s === 'abandoned') return badge('Abandoned','is-muted');
      if (s === 'draft') return badge('Draft','is-muted');
      if (s === 'demo') return badge('Demo','is-demo');
      return badge(p.status || '—','is-muted');
    }

    function dueToday(p){
      if (!p || !p.charges) return false;
      var now = new Date();
      var start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      var end = new Date(now.getFullYear(), now.getMonth(), now.getDate()+1);
      return (p.charges || []).some(function(c){
        var st = String(c.status||'').toLowerCase();
        if (st !== 'scheduled' && st !== 'overdue' && st !== 'demo_scheduled') return false;
        var d = new Date(c.dueAt);
        return d >= start && d < end;
      });
    }

    function filterPlans(plans){
      var out = plans.slice();
      if (filterStatus && filterStatus !== 'all'){
        out = out.filter(function(p){
          var s = String(p.status||'').toLowerCase();
          if (filterStatus === 'due-today') return dueToday(p);
          return s === filterStatus;
        });
      }
      if (q && q.trim()){
        var qq = q.trim().toLowerCase();
        out = out.filter(function(p){
          var a = String(p.externalOrderName||'').toLowerCase();
          var b = String(p.externalOrderId||'').toLowerCase();
          var c = String(p.customerName||'').toLowerCase();
          var d = String(p.customerEmail||'').toLowerCase();
          return a.includes(qq) || b.includes(qq) || c.includes(qq) || d.includes(qq);
        });
      }
      return out;
    }

    function onRowClick(p){
      setSelected(p);
    }

    function closeModal(){
      setSelected(null);
    }

    
    function copyText(label, text){
      try{
        if (navigator && navigator.clipboard && navigator.clipboard.writeText) {
          navigator.clipboard.writeText(String(text||''));
        } else {
          var ta=document.createElement('textarea'); ta.value=String(text||''); document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta);
        }
        alert(label + ' copied.');
      }catch(e){
        alert('Copy failed. Please copy manually.');
      }
    }

    function buildSetupLink(plan){
      if (!plan || !plan.publicToken) return '';
      var base=(cfg.apiBase||'').replace(/\/+$/,'');
      if (!base) return '';
      return base + '/storefront/plan/setup/' + plan.publicToken;
    }

    function buildCustomerLink(plan){
      if (!plan || !plan.id) return '';
      var base=(cfg.apiBase||'').replace(/\/+$/,'');
      if (!base) return '';
      return base + '/portal/' + plan.id;
    }

    async function refundInstallment(plan, charge){
      if (!plan || !charge) return;
      var ok = window.confirm('Refund this instalment? This will create a replacement scheduled payment to keep the plan balanced.');
      if (!ok) return;
      setActing(true); setErr(null);
      try{
        var r = await fetchJSON('/plans/' + encodeURIComponent(plan.id) + '/refund-charge', { method:'POST', data:{ chargeId: charge.id } });
        if (!r || !r.ok) throw new Error((r && (r.error || r.message)) || 'Refund failed');
        load();
      }catch(e){
        setErr(String(e && e.message ? e.message : e));
      }finally{
        setActing(false);
      }
    }
	
async function doCancel(plan){
      if (!plan) return;
      var ok = window.confirm('Cancel this plan? This will cancel remaining scheduled payments.');
      if (!ok) return;

      setActing(true); setErr(null);
      try{
        var r = await fetchJSON('/plans/' + encodeURIComponent(plan.id) + '/cancel', { method:'POST', data:{} });
        if (!r || !r.ok) throw new Error((r && (r.error || r.message)) || 'Cancel failed');
        // Best-effort: update Woo order status immediately
        try {
          var oid = parseInt(String(plan.externalOrderId||''),10);
          if (oid) await fetchJSON('/orders/' + oid + '/status', { method:'POST', data:{ status:'cancelled' } });
        } catch(_) {}
        closeModal();
        load();
      }catch(e){
        setErr(String(e && e.message ? e.message : e));
      }finally{
        setActing(false);
      }
    }

function updateCreate(k,v){
  setCreateForm(function(prev){ var n=Object.assign({},prev); n[k]=v; return n; });
}

async function submitManualCreate(){
  setActing(true); setErr(null);
  try{
    var total = parseInt(String(createForm.totalCents||'').replace(/[^0-9]/g,''),10);
    if (!total || total < 100) throw new Error('Enter a valid total amount (in cents).');
    if (!createForm.customerName || !createForm.customerEmail) throw new Error('Customer name and email are required.');

    var payload = {
      shopDomain: cfg.shopDomain,
      amountCents: total,
      currency: 'AUD',
      customerName: String(createForm.customerName),
      customerEmail: String(createForm.customerEmail),
      customerMobile: null,
      externalOrderId: 'manual-' + Date.now(),
      externalOrderName: 'Manual Plan',
      lineItems: [{ title: 'Manual Plan', quantity: 1, priceCents: total }],
      shippingAddress: {},
      shippingTitle: null,
      shippingPriceCents: 0,
      rawOrderJson: { manual: true, notes: String(createForm.notes||'') }
    };

    var r = await fetchJSON('/plans/manual-create', { method:'POST', data: payload });
    if (!r || !r.ok || !r.planUrl) throw new Error((r && (r.error||r.message)) || 'Create failed');

    copyText('Setup link', r.planUrl);
    setCreateOpen(false);
    setCreateForm({ totalCents:'', customerName:'', customerEmail:'', notes:'' });
    load();
  }catch(e){
    setErr(String(e && e.message ? e.message : e));
  }finally{
    setActing(false);
  }
}

    async function doDeletePending(plan){
      if (!plan) return;
      var ok = window.confirm('Delete this pending plan?');
      if (!ok) return;

      setActing(true); setErr(null);
      try{
        var r = await fetchJSON('/plans/' + encodeURIComponent(plan.id) + '/delete-pending', { method:'POST', data:{} });
        if (!r || !r.ok) throw new Error((r && (r.error || r.message)) || 'Delete failed');
        // Best-effort: update Woo order status immediately
        try {
          var oid = parseInt(String(plan.externalOrderId||''),10);
          if (oid) await fetchJSON('/orders/' + oid + '/status', { method:'POST', data:{ status:'cancelled' } });
        } catch(_) {}
        closeModal();
        load();
      }catch(e){
        setErr(String(e && e.message ? e.message : e));
      }finally{
        setActing(false);
      }
    }

    var plans = (res && res.ok && Array.isArray(res.plans)) ? res.plans : [];
    var filtered = filterPlans(plans);

    function summaryTile(label, value){
      return h(Card, { className:'flexilay-tile' },
        h('div', { className:'flexilay-tile-label' }, label),
        h('div', { className:'flexilay-tile-value' }, value)
      );
    }

    return h('div', null,
      h(PageHeader, {
        title: 'Your Plans',
        actions: h('div', null,
          h(comps.Button, { isSecondary:true, isBusy:loading, disabled:loading, onClick: load }, 'Refresh')
        )
      }),

      err ? h(NoticeBar, { status: 'error' }, err) : null,

      // Summary (reuse /status)
      (statusRes && statusRes.ok) ? h('div', { className:'flexilay-plans-summary' },
        h('div', { className:'flexilay-grid flexilay-grid-4' },
        summaryTile('Active plans', statusRes.activePlans || 0),
        summaryTile('Outstanding', centsToMoney(statusRes.totalOutstanding, statusRes.currency || 'AUD')),
        summaryTile('Collected', centsToMoney(statusRes.totalCollected, statusRes.currency || 'AUD')),
        summaryTile('Due today', statusRes.todayDueCount || 0)
        )
      ) : null,

      // Filters
      h('div', { className:'flexilay-plans-filters' },
        h(Card, null,
        h('div', { className:'flexilay-row', style:{justifyContent:'space-between', width:'100%'} },
          h('div', { className:'flexilay-row' },
            h('input', {
              className:'flexilay-input',
              placeholder:'Search order #, name, email…',
              value: q,
              onChange: function(e){ setQ(e.target.value); }
            }),
            h('select', {
              className:'flexilay-select',
              value: filterStatus,
              onChange: function(e){ setFilterStatus(e.target.value); }
            },
              h('option', { value:'all' }, 'All'),
              h('option', { value:'active' }, 'Active'),
              h('option', { value:'completed' }, 'Completed'),
              h('option', { value:'overdue' }, 'Overdue'),
              h('option', { value:'draft' }, 'Draft'),
              h('option', { value:'cancelled' }, 'Cancelled'),
              h('option', { value:'demo' }, 'Demo'),
              h('option', { value:'due-today' }, 'Due today')
            )
          ),
          h('div', { className:'flexilay-small' }, filtered.length + ' plans')
        )
        )
      ),

      // Table
      h('div', { className:'flexilay-plans-table' },
        h(Card, null,
        (plans.length === 0)
          ? h(NoticeBar, { status:'info' }, 'No plans found yet. Create a test plan in demo mode to populate this list.')
          : h('table', { className:'widefat striped', style:{cursor:'pointer'} },
              h('thead', null, h('tr', null,
                h('th', null, 'Order'),
                h('th', null, 'Customer'),
                h('th', null, 'Status'),
                h('th', null, ''),
                h('th', null, 'Total'),
                h('th', null, 'Deposit'),
                h('th', null, 'Remaining'),
                h('th', null, 'Frequency'),
                h('th', null, 'Next charge')
              )),
              h('tbody', null,
                filtered.map(function(p){
                  return h('tr', { key:p.id, onClick:function(){ onRowClick(p); } },
                    h('td', null, (p.externalOrderName || p.externalOrderId || p.id)),
                    h('td', null, (p.customerName || '') + (p.customerEmail ? ' ('+p.customerEmail+')' : '')),
                    h('td', null, planStatusBadge(p)),
                    h('td', null, centsToMoney(p.totalAmount, p.currency)),
                    h('td', null, centsToMoney(p.depositAmount, p.currency)),
                    h('td', null, centsToMoney(p.remainingAmount, p.currency)),
                    h('td', null, String(p.frequency || '—')),
                    h('td', null, (function(){
  if (p.nextChargeAt) return fmtDate(p.nextChargeAt);

  var next = null;
  (p.charges||[]).forEach(function(c){
    var st = String(c.status||'').toLowerCase();
    if (st === 'scheduled' || st === 'overdue' || st === 'demo_scheduled') {
      var d = new Date(c.dueAt);
      if (!isNaN(d.getTime())) {
        if (!next || d < next) next = d;
      }
    }
  });

  return next ? next.toLocaleString() : '';
})())

                  );
                })
              )
            )
        )
      ),
	  
createOpen ? h(comps.Modal, {
  title: 'Create Manual Plan',
  onRequestClose: function(){ setCreateOpen(false); },
  shouldCloseOnClickOutside: true
},
  h('div', { className:'flexilay-modal' },
    h('div', { className:'flexilay-small' }, 'Create a manual FlexiLay plan without a Woo checkout. This generates a setup link you can send to the customer.'),
    h('div', { className:'flexilay-grid', style:{marginTop:12} },
      h('label', null, h('div', { className:'flexilay-small' }, 'Total (cents)'), h('input', { className:'flexilay-input', value:createForm.totalCents, onChange:function(e){ updateCreate('totalCents', e.target.value); }, placeholder:'e.g. 144800' })),
      h('label', null, h('div', { className:'flexilay-small' }, 'Customer name'), h('input', { className:'flexilay-input', value:createForm.customerName, onChange:function(e){ updateCreate('customerName', e.target.value); } })),
      h('label', null, h('div', { className:'flexilay-small' }, 'Customer email'), h('input', { className:'flexilay-input', value:createForm.customerEmail, onChange:function(e){ updateCreate('customerEmail', e.target.value); } })),
      h('label', null, h('div', { className:'flexilay-small' }, 'Notes (optional)'), h('input', { className:'flexilay-input', value:createForm.notes, onChange:function(e){ updateCreate('notes', e.target.value); } }))
    ),
    h('div', { className:'flexilay-row', style:{marginTop:16, justifyContent:'flex-end'} },
      h(comps.Button, { isSecondary:true, disabled:acting, onClick:function(){ setCreateOpen(false); } }, 'Cancel'),
      h(comps.Button, { isPrimary:true, isBusy:acting, disabled:acting, onClick: submitManualCreate }, 'Create & Copy Setup Link')
    )
  )
) : null,

      // Detail modal
      selected ? h(comps.Modal, {
        title: 'Plan details',
        onRequestClose: closeModal,
        shouldCloseOnClickOutside: true
      },
        h('div', { className:'flexilay-modal' },
          h('div', { className:'flexilay-modal-head' },
            h('div', null,
              h('div', { className:'flexilay-h3' }, 'Order ' + (selected.externalOrderName || selected.externalOrderId || selected.id)),
              h('div', { className:'flexilay-small' }, (selected.customerName || '') + (selected.customerEmail ? ' • ' + selected.customerEmail : ''))
            ),
            h('div', null, planStatusBadge(selected))
          ),

          h('div', { className:'flexilay-grid flexilay-grid-3', style:{marginTop:12} },
            summaryTile('Total', centsToMoney(selected.totalAmount, selected.currency)),
            summaryTile('Deposit', centsToMoney(selected.depositAmount, selected.currency)),
            summaryTile('Remaining', centsToMoney(selected.remainingAmount, selected.currency))
          ),

          h('div', { style:{marginTop:14} },
            h('div', { className:'flexilay-small' }, 'Schedule'),
            h('div', { className:'flexilay-row', style:{marginTop:6} },
              badge(String(selected.frequency || '—'), 'is-muted'),
              badge(String(selected.numberOfPayments || '—') + ' payments', 'is-muted'),
              selected.nextChargeAt ? badge('Next: ' + fmtDate(selected.nextChargeAt), 'is-muted') : null
            )
          ),

          h('div', { style:{marginTop:16} },
            h('div', { className:'flexilay-small' }, 'Charges'),
            h('table', { className:'widefat striped', style:{marginTop:8} },
              h('thead', null, h('tr', null,
                h('th', null, '#'),
                h('th', null, 'Due'),
                h('th', null, 'Amount'),
                h('th', null, 'Status'),
                h('th', null, '')
              )),
              h('tbody', null, (selected.charges || []).map(function(c){
                return h('tr', { key:c.id },
                  h('td', null, c.sequence),
                  h('td', null, fmtDate(c.dueAt)),
                  h('td', null, centsToMoney(c.amount, selected.currency)),
                  h('td', null, badge(c.status || '—', (String(c.status||'').includes('overdue')?'is-bad':(String(c.status||'').includes('paid')?'is-ok':'is-muted')))),
                  h('td', null,
                    (function(){
                      var st = String(c.status||'').toLowerCase();
                      var can = (c.sequence > 1) && (st === 'paid' || st === 'succeeded');
                      return can ? h(comps.Button, { isSecondary:true, disabled:acting, onClick:function(e){ if(e&&e.stopPropagation) e.stopPropagation(); refundInstallment(selected, c); } }, 'Refund') : '';
                    })()
                  )
                );
              }))
            )
          ),

          h('div', { className:'flexilay-row', style:{marginTop:16, justifyContent:'flex-end'} },
            h(comps.Button, { isSecondary:true, disabled: acting, onClick:function(){ copyText('Plan link', buildCustomerLink(selected)); } }, 'Copy plan link'),
            h(comps.Button, { isSecondary:true, disabled: acting, onClick:function(){ copyText('Setup link', buildSetupLink(selected)); } }, 'Copy setup link'),
            h(comps.Button, { isSecondary:true, onClick: closeModal, disabled: acting }, 'Close'),
            (String(selected.status||'').toLowerCase() === 'draft' || String(selected.status||'').toLowerCase() === 'abandoned')
              ? h(comps.Button, { isDestructive:true, onClick:function(){ doDeletePending(selected); }, isBusy: acting, disabled: acting }, 'Delete pending')
              : h(comps.Button, { isDestructive:true, onClick:function(){ doCancel(selected); }, isBusy: acting, disabled: acting }, 'Cancel plan')
          )
        )
      ) : null
    );
  }

function Settings() {
  var _a = useState(null), data = _a[0], setData = _a[1];
  var _b = useState(null), err = _b[0], setErr = _b[1];
  var _c = useState(false), saving = _c[0], setSaving = _c[1];

  var _d = useState({
    passFeesToCustomer: false,
    depositEnabled: true,
    depositMin: 10,
    depositMax: 50,
    freqWeekly: true,
    freqFortnightly: true,
    freqMonthly: true,
    paymentsEnabled: true,
    minPayments: 4,
    maxPayments: 12,
    demoEnabled: false,
    demoDurationMins: 60,
    demoUntil: ""
  }), form = _d[0], setForm = _d[1];

  var _e = useState(!!cfg.enableCrisp), enableCrisp = _e[0], setEnableCrisp = _e[1];

  function load() {
    setErr(null);
    return fetchJSON('/settings').then(function (r) {
      setData(r);

      var s = (r && r.settings) ? r.settings : (r && r.ok && r.data && r.data.settings ? r.data.settings : null);
      if (!s || typeof s !== 'object') return r;

      var passFees = (s.passFeesToCustomer === true);

      var dep = (s.deposit && typeof s.deposit === 'object') ? s.deposit : {};
      var depEnabled = (dep.enabled !== false);
      var depMin = (typeof dep.min === 'number') ? dep.min : 10;
      var depMax = (typeof dep.max === 'number') ? dep.max : 50;

      var f = (s.frequencies && typeof s.frequencies === 'object') ? s.frequencies : {};
      var w = (f.weekly !== false);
      var fn = (f.fortnightly !== false);
      var m = (f.monthly !== false);

      var p = (s.payments && typeof s.payments === 'object') ? s.payments : {};
      var pEnabled = (p.enabled !== false);
      var pMin = (typeof p.min === 'number') ? p.min : 4;
      var pMax = (typeof p.max === 'number') ? p.max : 12;

      var dm = (s.demoMode && typeof s.demoMode === 'object') ? s.demoMode : {};
      var dmEnabled = !!dm.enabled;
      var dmUntil = dm.until ? String(dm.until) : "";

      var demoExpired = false;
      if (dmEnabled && dmUntil) {
        var t = new Date(dmUntil);
        if (!isNaN(t.getTime()) && t.getTime() <= Date.now()) demoExpired = true;
      }
      if (demoExpired) {
        dmEnabled = false;
        dmUntil = "";
        fetchJSON('/settings', { method:'POST', data:{ settings: Object.assign({}, s, { demoMode:{ enabled:false, until:null } }) } })
          .then(function(){})
          .catch(function(){});
      }

      window.__FLEXILAY_DEMO_LOADED_ENABLED = dmEnabled;

      setForm(function(prev){
        return Object.assign({}, prev, {
          passFeesToCustomer: passFees,
          depositEnabled: depEnabled,
          depositMin: depMin,
          depositMax: depMax,
          freqWeekly: w,
          freqFortnightly: fn,
          freqMonthly: m,
          paymentsEnabled: pEnabled,
          minPayments: pMin,
          maxPayments: pMax,
          demoEnabled: dmEnabled,
          demoUntil: dmUntil || "",
        });
      });

      return r;
    }).catch(function (e) {
      setErr(String(e && e.message ? e.message : e));
    });
  }

  useEffect(function () { load(); }, []);

  function update(k, v) {
    setForm(function (prev) {
      var next = Object.assign({}, prev);
      next[k] = v;
      return next;
    });
  }

  function save() {
    setSaving(true);
    setErr(null);

    var settings = {
      passFeesToCustomer: !!form.passFeesToCustomer,
      deposit: { enabled: !!form.depositEnabled, min: Number(form.depositMin || 10), max: Number(form.depositMax || 50) },
      frequencies: { weekly: !!form.freqWeekly, fortnightly: !!form.freqFortnightly, monthly: !!form.freqMonthly },
      payments: { enabled: !!form.paymentsEnabled, min: Number(form.minPayments || 4), max: Number(form.maxPayments || 12) },
      demoMode: { enabled: !!form.demoEnabled, until: null },
    };

    var wasDemoEnabled = !!window.__FLEXILAY_DEMO_LOADED_ENABLED;
    var willDemoEnabled = !!settings.demoMode.enabled;

    if (willDemoEnabled && !wasDemoEnabled) {
      var typed = String(prompt("Type DEMO to enable transaction-free Demo mode for this merchant.") || "").trim().toUpperCase();
      if (typed !== "DEMO") {
        setSaving(false);
        setErr("Demo mode not enabled (confirmation failed).");
        return;
      }
    }

    if (willDemoEnabled) {
      var mins = Math.max(1, Number(form.demoDurationMins || 60));
      var until = new Date(Date.now() + mins * 60 * 1000);
      settings.demoMode.until = until.toISOString();
    } else {
      settings.demoMode.until = null;
    }

    fetchJSON('/settings', { method:'POST', data: { settings: settings } })
      .then(function (r) {
        setSaving(false);
        setData(r);
        fetchJSON('/crisp', { method:'POST', data:{ enabled: !!enableCrisp } }).catch(function(){});
        load();
      })
      .catch(function (e) {
        setSaving(false);
        setErr(String(e && e.message ? e.message : e));
      });
  }

  function formatUntil(iso) {
    if (!iso) return "—";
    var d = new Date(iso);
    if (isNaN(d.getTime())) return "—";
    return d.toLocaleString();
  }

  return h('div', null,
    h(PageHeader, {
      title: 'FlexiLay Settings',
      actions: h('div', null,
        h(comps.Button, { isSecondary: true, onClick: load, disabled: saving }, 'Refresh'),
        h('span', { style: { display: 'inline-block', width: 8 } }),
        h(comps.Button, { isPrimary: true, onClick: save, isBusy: saving, disabled: saving }, 'Save Settings')
      )
    }),

    err ? h(NoticeBar, { status: 'error' }, err) : null,

    h('div', { className:'flexilay-settings-section' },
      h(Card, null,
        h('h3', { className:'flexilay-h3' }, 'Configure FlexiLay for WooCommerce'),
        h('p', { className:'flexilay-p' }, 'These settings control how FlexiLay plans are offered at checkout (deposit range, allowed frequencies, number of payments, fees, and demo mode).')
      )
    ),

    h('div', { className:'flexilay-settings-section' },
      h('div', { className: 'flexilay-grid flexilay-grid-2' },
        h(Card, null,
          h('h3', { className: 'flexilay-h3' }, 'Fees'),
          h('label', { className: 'flexilay-check' },
            h('input', { type: 'checkbox', checked: !!form.passFeesToCustomer, onChange: function(){ update('passFeesToCustomer', !form.passFeesToCustomer); } }),
            h('span', null, 'Add FlexiLay and card fees onto customer payments')
          ),

          h('div', { style:{height:12} }),
          h('h3', { className: 'flexilay-h3' }, 'Add FlexiLay Support'),
          h('label', { className:'flexilay-check' },
            h('input', { type:'checkbox', checked: !!enableCrisp, onChange: function(){ setEnableCrisp(!enableCrisp); } }),
            h('span', null, 'Enable Support Chat (Crisp)')
          ),
          h('p', { className:'flexilay-small' }, 'Adds the FlexiLay support chat bubble to FlexiLay admin pages. Only your shop domain is shared for support context.')
        ),

        h(Card, null,
          h('h3', { className: 'flexilay-h3' }, 'Plan parameters'),

          h('label', { className: 'flexilay-check' },
            h('input', { type: 'checkbox', checked: !!form.depositEnabled, onChange: function(){ update('depositEnabled', !form.depositEnabled); } }),
            h('span', null, 'Specify deposit range')
          ),

          h('div', { className: 'flexilay-row', style: { marginTop: 8 } },
            h('span', { className: 'flexilay-small' }, 'Min %'),
            h('input', { type:'number', min:0, max:100, value: String(form.depositMin), onChange: function(e){ update('depositMin', e.target.value); }, className:'flexilay-num' }),
            h('span', { className: 'flexilay-small' }, 'Max %'),
            h('input', { type:'number', min:0, max:100, value: String(form.depositMax), onChange: function(e){ update('depositMax', e.target.value); }, className:'flexilay-num' })
          ),

          h('div', { style: { height: 12 } }),
          h('div', { className: 'flexilay-small' }, 'Allowed payment frequencies'),
          h('div', { className: 'flexilay-grid flexilay-grid-3', style: { marginTop: 6 } },
            h('label', { className: 'flexilay-check' }, h('input', { type:'checkbox', checked: !!form.freqWeekly, onChange: function(){ update('freqWeekly', !form.freqWeekly); } }), h('span', null, 'Weekly')),
            h('label', { className: 'flexilay-check' }, h('input', { type:'checkbox', checked: !!form.freqFortnightly, onChange: function(){ update('freqFortnightly', !form.freqFortnightly); } }), h('span', null, 'Fortnightly')),
            h('label', { className: 'flexilay-check' }, h('input', { type:'checkbox', checked: !!form.freqMonthly, onChange: function(){ update('freqMonthly', !form.freqMonthly); } }), h('span', null, 'Monthly'))
          ),

          h('div', { style: { height: 12 } }),
          h('label', { className: 'flexilay-check' },
            h('input', { type: 'checkbox', checked: !!form.paymentsEnabled, onChange: function(){ update('paymentsEnabled', !form.paymentsEnabled); } }),
            h('span', null, 'Specify min / max payments')
          ),

          h('div', { className: 'flexilay-row', style: { marginTop: 8 } },
            h('span', { className: 'flexilay-small' }, 'Min'),
            h('input', { type:'number', min:1, max:52, value: String(form.minPayments), onChange: function(e){ update('minPayments', e.target.value); }, className:'flexilay-num' }),
            h('span', { className: 'flexilay-small' }, 'Max'),
            h('input', { type:'number', min:1, max:52, value: String(form.maxPayments), onChange: function(e){ update('maxPayments', e.target.value); }, className:'flexilay-num' })
          )
        )
      )
    ),

    h('div', { className:'flexilay-settings-section' },
      h(Card, null,
        h('h3', { className: 'flexilay-h3' }, 'Test Mode (no payments at checkout)'),
        h('div', { className: 'flexilay-warning' },
          h('div', { className: 'flexilay-warning-title' }, '⚠ Transaction-free testing'),
          h('div', { className: 'flexilay-small' }, 'When enabled, customers can create plans and complete checkout without any real Stripe charge. Use for testing only.')
        ),

        h('label', { className: 'flexilay-check' },
          h('input', { type: 'checkbox', checked: !!form.demoEnabled, onChange: function(){ update('demoEnabled', !form.demoEnabled); } }),
          h('span', null, 'Enable demo mode (no real payments)')
        ),

        h('div', { className: 'flexilay-row', style: { marginTop: 10 } },
          h('span', { className: 'flexilay-small' }, 'Auto-disable after'),
          h('select', { value: String(form.demoDurationMins || 60), onChange: function(e){ update('demoDurationMins', Number(e.target.value || 60)); } },
            h('option', { value: '15' }, '15 minutes'),
            h('option', { value: '60' }, '1 hour'),
            h('option', { value: '240' }, '4 hours'),
            h('option', { value: '1440' }, '24 hours')
          ),
          h('span', { className: 'flexilay-small' }, 'Current expiry:'),
          h('span', { className: 'flexilay-mono' }, formatUntil(form.demoUntil))
        )
      )
    )
  );
}
                                                            
function App() {
    var pageMatch = (window.location.search || '').match(/page=([^&]+)/);
    var page = pageMatch ? pageMatch[1] : 'flexilay';

    var view = Overview;
    if (page === 'flexilay-onboarding') view = Onboarding;
    if (page === 'flexilay-overview' || page === 'flexilay') view = Overview;
    if (page === 'flexilay-plans') view = Plans;
    if (page === 'flexilay-settings') view = Settings;

    return h('div', { className: 'flexilay-admin-root' }, h(view));
  }

  var root = document.querySelector('#flexilay-admin-app .flexilay-admin-shell') || document.getElementById('flexilay-admin-app');
  if (!root) return;

  el.render(h(ErrorBoundary, null, h(App)), root);
})();
