/* Adeyy app — shell, routing, state. Live API version. */

function AdeyyApp() {
  const D = window.AdeyyData;
  const API = window.AdeyyAPI;

  const [state, setState] = React.useState(null);
  const [route, setRoute] = React.useState({ page: 'links', params: {} });
  const [loading, setLoading] = React.useState(true);
  const [toasts, setToasts] = React.useState([]);
  const [cardCb, setCardCb] = React.useState(null);

  /* ── Bootstrap: load live state ─────────────────────────────────────── */
  React.useEffect(() => {
    API.loadLiveState().then((liveState) => {
      if (!liveState) return; /* redirected to login */

      if (liveState.needsOnboarding) {
        API.showOnboarding(liveState.user, () => {
          /* Reload after onboarding */
          API.loadLiveState().then((s) => {
            if (s && !s.needsOnboarding) {
              setState(s);
              setLoading(false);
            }
          });
        });
        return;
      }

      setState(liveState);
      setLoading(false);
    }).catch((err) => {
      console.error('[AdeyyApp] Bootstrap error:', err);
      setLoading(false);
    });
  }, []);

  const toast = React.useCallback((msg) => {
    const id = Date.now() + Math.random();
    setToasts((t) => t.concat([{ id, msg }]));
    setTimeout(() => setToasts((t) => t.filter((x) => x.id !== id)), 2800);
  }, []);

  /* ── App object (same interface as prototype) ────────────────────────── */
  const app = React.useMemo(() => {
    if (!state) return null;
    return {
      state,
      loading,
      toast,
      go: (page, params) => { setRoute({ page, params: params || {} }); window.scrollTo(0, 0); },
      update: (fn) => setState((s) => { const n = JSON.parse(JSON.stringify(s)); fn(n); return n; }),

      /* Campaigns — live API */
      addCampaign: async (name) => {
        if (!name) return null;
        try {
          const result = await API.createCampaign(name);
          const id = result.id;
          setState((s) => {
            const n = JSON.parse(JSON.stringify(s));
            n.campaigns.push({ id, name, created: new Date().toISOString() });
            return n;
          });
          return id;
        } catch (e) {
          toast('Could not create campaign: ' + e.message);
          return null;
        }
      },

      /* Link status — live API with trial/card gate */
      setLinkStatus: async (id, on) => {
        if (on && !state.billing.canActivate) {
          app.setCardPrompt(() => app.setLinkStatus(id, true));
          return;
        }
        try {
          await API.setLinkStatus(id, on);
          setState((s) => {
            const n = JSON.parse(JSON.stringify(s));
            const l = n.links.find((x) => x.id === id);
            if (l) l.status = on ? 'active' : 'inactive';
            return n;
          });
          const trialActive = !!(state.trial && state.trial.active);
          toast(on
            ? (trialActive ? 'Link activated. Free during your trial period.' : 'Switched on. Live now, $1.00 a month prorated from today')
            : 'Switched off. Scans will land on the fallback page');
          /* Refresh billing */
          API.getBillingStatus().then((b) => {
            setState((s) => {
              const n = JSON.parse(JSON.stringify(s));
              n.billing.card = b.card ? { brand: b.card.brand, last4: b.card.last4, exp: b.card.expMonth + '/' + String(b.card.expYear).slice(-2) } : null;
              n.billing.canActivate = !!(b.card) || !!(s.trial && s.trial.active);
              return n;
            });
          }).catch(() => {});
        } catch (e) {
          if (e.message && e.message.includes('card on file')) {
            app.setCardPrompt(() => app.setLinkStatus(id, true));
          } else {
            toast('Error: ' + e.message);
          }
        }
      },

      /* Card prompt — uses Stripe.js modal */
      setCardPrompt: (cb) => {
        if (cb === null) { setCardCb(null); return; }
        API.showStripeCardModal(
          async (billing) => {
            /* Card saved successfully — update state */
            setState((s) => {
              const n = JSON.parse(JSON.stringify(s));
              n.billing.card = billing.card ? {
                brand: billing.card.brand,
                last4: billing.card.last4,
                exp: billing.card.expMonth + '/' + String(billing.card.expYear).slice(-2)
              } : null;
              return n;
            });
            toast('Card saved. You can switch codes on now');
            if (cb) setTimeout(cb, 0);
          },
          () => { /* cancelled */ }
        );
      },
      resolveCardPrompt: () => { setCardCb((cb) => { if (cb) setTimeout(cb, 0); return null; }); },

      /* Refresh links from server */
      refreshLinks: async () => {
        try {
          const data = await API.listLinks({ limit: 200 });
          setState((s) => {
            const n = JSON.parse(JSON.stringify(s));
            n.links = (data.links || []).map(API.adaptLink);
            n.campaigns = (data.campaigns || []).map(API.adaptCampaign);
            return n;
          });
        } catch (e) {
          console.error('[AdeyyApp] refreshLinks error:', e);
        }
      },

      /* Refresh billing */
      refreshBilling: async () => {
        try {
          const b = await API.getBillingStatus();
          const invs = await API.getInvoices();
          setState((s) => {
            const n = JSON.parse(JSON.stringify(s));
            n.billing.card = b.card ? { brand: b.card.brand, last4: b.card.last4, exp: b.card.expMonth + '/' + String(b.card.expYear).slice(-2) } : null;
            n.billing.invoices = (invs || []).map((inv) => ({
              id: inv.number || inv.id,
              period: new Date(inv.date).toLocaleString('en-AU', { month: 'short', year: '2-digit' }),
              amount: inv.amount,
              status: inv.status,
              pdfUrl: inv.pdfUrl
            }));
            return n;
          });
        } catch (e) {
          console.error('[AdeyyApp] refreshBilling error:', e);
        }
      },

      /* Refresh team */
      refreshTeam: async () => {
        try {
          const team = await API.getTeam();
          setState((s) => {
            const n = JSON.parse(JSON.stringify(s));
            n.team = team.map(API.adaptTeamMember);
            return n;
          });
        } catch (e) {
          console.error('[AdeyyApp] refreshTeam error:', e);
        }
      },

      /* Legacy resetData — no-op in live mode */
      resetData: () => { toast('This is the live app. Data cannot be reset.'); }
    };
  }, [state, loading, toast]);

  if (!state || !app) {
    return (
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', height: '100vh', background: 'var(--paper)' }}>
        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 16 }}>
          <img src="/adeyy/assets/adeyy-ink.svg" alt="Adeyy" style={{ height: 32 }} />
          <div style={{ display: 'flex', gap: 6 }}>
            {[0, 1, 2].map((i) => (
              <div key={i} style={{
                width: 8, height: 8, borderRadius: '50%', background: 'var(--ink-40)',
                animation: 'pulse 1.2s ease-in-out infinite',
                animationDelay: (i * 0.2) + 's'
              }} />
            ))}
          </div>
        </div>
        <style>{`@keyframes pulse { 0%,80%,100%{opacity:0.3;transform:scale(0.8)} 40%{opacity:1;transform:scale(1)} }`}</style>
      </div>
    );
  }

  const { page, params } = route;
  const navGroups = [
    { label: null, items: [['links', 'link', 'Links'], ['bulk', 'upload', 'Bulk create'], ['campaigns', 'folder', 'Campaigns']] },
    { label: 'Measure', items: [['analytics', 'chart', 'Analytics']] },
    { label: 'Account', items: [['billing', 'card', 'Billing'], ['settings', 'settings', 'Settings']] }
  ];
  const activeNav = { links: 'links', create: 'links', detail: 'links', qr: 'links', bulk: 'bulk', campaigns: 'campaigns', analytics: 'analytics', billing: 'billing', settings: 'settings' }[page];

  return (
    <div className="appshell">
      <aside className="aside">
        <a className="brand" href="/">
          <img src="/adeyy/assets/adeyy-ink.svg" alt="Adeyy" />
          <span className="by">By ProDesk</span>
        </a>
        {navGroups.map((g, gi) => (
          <React.Fragment key={gi}>
            {g.label ? <div className="grp">{g.label}</div> : null}
            {g.items.map(([key, icon, label]) => (
              <button key={key} className={'navitem' + (activeNav === key ? ' active' : '')} onClick={() => app.go(key)}>
                <Icon name={icon} />{label}
              </button>
            ))}
          </React.Fragment>
        ))}
        {/* Trial banner */}
        {state.trial && state.trial.active && (() => {
          const daysLeft = Math.ceil((new Date(state.trial.endsAt) - Date.now()) / 86400000);
          const urgent = daysLeft <= 7;
          return (
            <div style={{
              margin: '8px 12px',
              padding: '10px 12px',
              borderRadius: 6,
              background: urgent ? 'rgba(220,38,38,0.08)' : 'rgba(14,14,12,0.05)',
              border: '1px solid ' + (urgent ? 'rgba(220,38,38,0.25)' : 'rgba(14,14,12,0.1)'),
              fontSize: 12
            }}>
              <div style={{ fontWeight: 600, color: urgent ? '#dc2626' : 'var(--ink)', marginBottom: 3 }}>
                {daysLeft <= 0 ? 'Trial expired' : `${daysLeft} day${daysLeft === 1 ? '' : 's'} left in trial`}
              </div>
              {!state.billing.card && (
                <div style={{ color: 'var(--ink-60)', lineHeight: 1.4 }}>
                  {urgent ? 'Add a card now to keep your links live after the trial.' : 'Add a card before your trial ends to keep links active.'}
                  <button
                    onClick={() => app.go('billing')}
                    style={{ display: 'block', marginTop: 6, fontSize: 11.5, fontWeight: 600, color: urgent ? '#dc2626' : 'var(--accent)', background: 'none', border: 'none', padding: 0, cursor: 'pointer', textDecoration: 'underline' }}
                  >Add card →</button>
                </div>
              )}
            </div>
          );
        })()}
        <div className="foot">
          <div className="vendor">
            <span className="avatar">{state.vendor.initials || state.vendor.name.slice(0, 2).toUpperCase()}</span>
            {state.vendor.name}
          </div>
          <span className="by2"><a href="/">A ProDesk Power tool</a></span>
        </div>
      </aside>

      <main className="amain">
        {page === 'links' ? <LinksHome app={app} /> : null}
        {page === 'create' ? <CreateLink app={app} /> : null}
        {page === 'detail' ? <LinkDetail app={app} linkId={params.linkId} /> : null}
        {page === 'qr' ? <QrCustomise app={app} linkId={params.linkId} /> : null}
        {page === 'analytics' ? <Analytics app={app} linkId={params.linkId} campaignId={params.campaignId} key={(params.linkId || '') + (params.campaignId || '')} /> : null}
        {page === 'campaigns' ? <Campaigns app={app} /> : null}
        {page === 'bulk' ? <BulkCreate app={app} /> : null}
        {page === 'billing' ? <Billing app={app} /> : null}
        {page === 'settings' ? <Settings app={app} /> : null}
      </main>

      <Toasts items={toasts} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById('root')).render(<AdeyyApp />);
