// ─────────────────────────────────────────────
// DEV_AppDetail.jsx — App detail with tabs
// Tabs: App | Database | Design | Users | Security | Logs | API
// ─────────────────────────────────────────────

const TABS = [
  { id:'app',      label:'App'      },
  { id:'database', label:'Database' },
  { id:'design',   label:'Design'   },
  { id:'users',    label:'Users'    },
  { id:'security', label:'Security' },
  { id:'logs',     label:'Logs'     },
  { id:'api',      label:'API'      },
];

const REGIONS = [
  { value:'east', label:'US East',   flag:'🇺🇸' },
  { value:'west', label:'US West',   flag:'🇺🇸' },
  { value:'eu',   label:'Europe',    flag:'🇪🇺' },
  { value:'uk',   label:'UK',        flag:'🇬🇧' },
  { value:'au',   label:'Australia', flag:'🇦🇺' },
  { value:'jp',   label:'Japan',     flag:'🇯🇵' },
];

function formatDate(d) {
  if (!d) return '—';
  try { return new Date(d).toLocaleDateString('en-US',
    { year:'numeric', month:'short', day:'numeric', hour:'2-digit', minute:'2-digit' }); }
  catch(e) { return d; }
}

function formatDateShort(d) {
  if (!d) return '—';
  const diff = Date.now() - new Date(d).getTime();
  const m = Math.floor(diff / 60000);
  if (m < 1)  return 'just now';
  if (m < 60) return `${m}m ago`;
  const h = Math.floor(m / 60);
  if (h < 24) return `${h}h ago`;
  const dy = Math.floor(h / 24);
  if (dy < 7) return `${dy}d ago`;
  return new Date(d).toLocaleDateString('en-US', { month:'short', day:'numeric' });
}

function fmtStorage(bytes) {
  if (!bytes) return '0 B';
  if (bytes < 1024)           return bytes + ' B';
  if (bytes < 1024*1024)      return (bytes/1024).toFixed(1) + ' KB';
  if (bytes < 1024*1024*1024) return (bytes/1024/1024).toFixed(1) + ' MB';
  return (bytes/1024/1024/1024).toFixed(2) + ' GB';
}

// ── App Stats — pulls live data from /v6/dev/stats ──
function AppStats({ app }) {
  const [stats,   setStats]   = React.useState(null);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    apiFetch(`${API_BASE}/v6/dev/stats?app=${app.app_id}`)
      .then(r => r.json())
      .then(data => { if (data.status === 'ok') setStats(data.stats); })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [app.app_id]);

  const val = (v) => loading ? '…' : (v == null ? '—' : Number(v).toLocaleString());

  return (
    <>
      {[
        { label:'Tables',        v: val(stats?.tables)   },
        { label:'Records',       v: val(stats?.records)  },
        { label:'Active Users',  v: val(stats?.users)    },
        { label:'Files',         v: val(stats?.files)    },
        { label:'Storage Used',  v: loading ? '…' : fmtStorage(stats?.storage) },
        { label:'Last Activity', v: loading ? '…' : formatDateShort(stats?.last_activity) },
      ].map(row => (
        <div key={row.label} style={ST.statRow}>
          <div style={ST.statLabel}>{row.label}</div>
          <div style={ST.statVal}>{row.v}</div>
        </div>
      ))}
    </>
  );
}

// ── Recent Activity — last 10 login events ──
function RecentActivity({ app, onViewAll }) {
  const [logs,    setLogs]    = React.useState([]);
  const [loading, setLoading] = React.useState(true);

  React.useEffect(() => {
    apiFetch(`${API_BASE}/v6/dev/logs?app=${app.app_id}&limit=10&type=access`)
      .then(r => r.json())
      .then(data => { if (data.status === 'ok') setLogs(data.logs || []); })
      .catch(() => {})
      .finally(() => setLoading(false));
  }, [app.app_id]);

  if (loading) return <div style={{ color:'#94a3b8', fontSize:13, padding:'10px 0' }}>Loading…</div>;
  if (!logs.length) return <div style={{ color:'#94a3b8', fontSize:13, padding:'10px 0' }}>No activity yet.</div>;

  return (
    <div>
      {logs.map(log => {
        let d = {};
        try { d = JSON.parse(log.log_data || '{}'); } catch(e) {}
        return (
          <div key={log.log_id} style={ST.activityRow}>
            <div style={ST.activityTime}>{formatDateShort(log.log_date_insert)}</div>
            <div style={{ flex:1, minWidth:0 }}>
              <div style={ST.activityEmail}>{d.email || log.log_user || '—'}</div>
              <div style={ST.activityMeta}>{d.location || d.ip || log.log_ip || ''}</div>
            </div>
          </div>
        );
      })}
      <button onClick={onViewAll} style={ST.viewAllBtn}>View all logs →</button>
    </div>
  );
}

// ── Placeholder tab ──────────────────────────
function ComingSoon({ label }) {
  return (
    <div style={{ textAlign:'center', padding:'80px 0', color:'#94a3b8' }}>
      <div style={{ fontSize:36, marginBottom:16 }}>⚙</div>
      <div style={{ fontSize:16, fontWeight:600, color:'#374151', marginBottom:8 }}>{label}</div>
      <div style={{ fontSize:13 }}>Coming soon</div>
    </div>
  );
}

// ── Custom Domain modal ──────────────────────
// First of the "DO Add-On" modals. Pattern to reuse for paid add-ons
// (API Access, AI Indexing, Remote Backup, more users/storage): explain the
// add-on, show setup steps, then a confirm/agree action that will eventually
// create a billing item + kick off Stripe. For now the action is "coming soon".
function CustomDomainModal({ appId, cnameTarget, onClose }) {
  const [copied, setCopied] = React.useState(false);

  function copyTarget() {
    try {
      navigator.clipboard.writeText(cnameTarget);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch(e) {}
  }

  return (
    <div style={MD.overlay} onClick={onClose}>
      <div style={MD.modal} onClick={e => e.stopPropagation()}>
        <div style={MD.head}>
          <div style={MD.title}>🧭 Custom Domain</div>
          <button style={MD.close} onClick={onClose}>×</button>
        </div>

        <div style={MD.body}>
          <p style={MD.lead}>
            Point your own domain at this app — e.g. <code style={MD.code}>app.yourcompany.com</code>{' '}
            instead of the default DataObjects End Point URL.
          </p>

          <div style={MD.stepLabel}>Setup</div>
          <ol style={MD.steps}>
            <li>Go to your DNS provider for the domain you want to use.</li>
            <li>
              Add a <strong>CNAME</strong> record pointing your chosen hostname to:
              <div style={MD.cnameBox}>
                <code style={MD.cnameTarget}>{cnameTarget}</code>
                <button type="button" style={MD.copyBtn} onClick={copyTarget}>
                  {copied ? '✓ Copied' : 'Copy'}
                </button>
              </div>
            </li>
            <li>Save the record and allow time for DNS to propagate (usually minutes, up to 24h).</li>
          </ol>

          <div style={MD.comingSoon}>
            <strong>Coming soon.</strong> Custom domains will be available as an add-on.
            We'll show pricing and confirmation here before any charges apply.
          </div>
        </div>

        <div style={MD.foot}>
          <button style={MD.btnGhost} onClick={onClose}>Close</button>
          <button style={MD.btnPrimaryDisabled} disabled title="Coming soon">
            Add to App
          </button>
        </div>
      </div>
    </div>
  );
}

// ── App tab ───────────────────────────────────
function AppTab({ app, jwt, onAppUpdate, onSwitchTab }) {
  const [name,    setName]    = React.useState(app.app_name || '');
  const [desc,    setDesc]    = React.useState(app.app_desc || '');
  const [active,  setActive]  = React.useState(app.app_status == 1);
  const [saving,  setSaving]  = React.useState(false);
  const [saved,   setSaved]   = React.useState(false);
  const [error,   setError]   = React.useState(null);
  const [showDomainModal, setShowDomainModal] = React.useState(false);

  const region = REGIONS.find(r => r.value === app.app_data);
  const endpoint = `https://app.dataobjects.com/${app.app_id}`;
  const CNAME_TARGET = 'do-app.pages.dev';

  async function handleSave(e) {
    e.preventDefault();
    setSaving(true); setSaved(false); setError(null);
    try {
      const res  = await apiFetch(`${API_BASE}/v6/dev/apps/${app.app_id}`, {
        method: 'POST',
        body: JSON.stringify({ name: name.trim(), desc: desc.trim(), status: active ? 1 : 0 }),
      });
      const data = await res.json();
      if (data.status !== 'ok') throw new Error(data.message);
      setSaved(true);
      onAppUpdate({ ...app, app_name: name.trim(), app_desc: desc.trim(), app_status: active ? 1 : 0 });
      setTimeout(() => setSaved(false), 3000);
    } catch(err) { setError(err.message); }
    setSaving(false);
  }

  return (
    <div style={ST.grid}>

      {/* App Info */}
      <div style={ST.card}>
        <div style={ST.cardHeader}>App Info</div>
        {error && <div style={ST.error}>{error}</div>}
        <form onSubmit={handleSave}>
          {/* ── Active / Inactive toggle (moved to top) ── */}
          <div style={ST.toggleRowTop}>
            <div>
              <div style={ST.toggleLabel}>App Status</div>
              <div style={ST.toggleSub}>Inactive apps show a maintenance notice to users</div>
            </div>
            <div style={{ display:'flex', alignItems:'center', gap:10 }}>
              <div style={ST.toggleTrack(active)} onClick={() => setActive(v => !v)}>
                <div style={ST.toggleThumb(active)} />
              </div>
              <span style={{ fontSize:13, fontWeight:600, color: active ? '#16a34a' : '#94a3b8',
                             minWidth:52 }}>
                {active ? 'Active' : 'Inactive'}
              </span>
            </div>
          </div>

          <label style={ST.label}>App Name</label>
          <input style={ST.input} type="text" value={name}
            onChange={e => setName(e.target.value)} required />

          <label style={ST.label}>Description <span style={ST.optional}>(optional)</span></label>
          <textarea style={{ ...ST.input, height:80, resize:'vertical' }}
            value={desc} onChange={e => setDesc(e.target.value)}
            placeholder="What is this app for?" />

          {/* Save (moved under description) */}
          <div style={{ display:'flex', justifyContent:'flex-end' }}>
          <button type="submit" style={ST.saveBtn} disabled={saving}>
            {saving ? 'Saving…' : saved ? '✓ Saved' : 'Save'}
          </button>
          </div>

          {/* Endpoint */}
          <div style={ST.infoBlock}>
            <div style={ST.infoIcon}>🌐</div>
            <div>
              <div style={ST.infoLabel}>End Point</div>
              <div style={ST.infoSub}>Main URL for your application</div>
              <a href={endpoint} target="_blank" rel="noopener" style={ST.infoLink}>
                {endpoint} ↗
              </a>
            </div>
          </div>

          {/* Custom Domain (new) */}
          <div style={ST.infoBlock}>
            <div style={ST.infoIcon}>🧭</div>
            <div style={{ flex:1 }}>
              <div style={ST.infoLabel}>Custom Domain (URL)</div>
              <div style={ST.infoSub}>Create a custom domain for your app.</div>
              <div style={{ display:'flex', justifyContent:'flex-end' }}>
              <button type="button" style={ST.addOnBtn}
                onClick={() => setShowDomainModal(true)}>
                + Create Custom URL
              </button>
              </div>
            </div>
          </div>

          {/* Location */}
          {/*<div style={ST.infoBlock}>
            <div style={ST.infoIcon}>📍</div>
            <div>
              <div style={ST.infoLabel}>Location</div>
              <div style={ST.infoSub}>Location of your database and content</div>
              <div style={ST.infoValue}>
                {region ? `${region.flag} ${region.label}` : app.app_data}
              </div>
            </div>
          </div>*/}
        </form>
      </div>

      {/* App Stats */}
      <div style={ST.card}>
        <div style={ST.cardHeader}>App Stats</div>

          {/* Location */}
          <div style={ST.infoBlock}>
            <div style={ST.infoIcon}>📍</div>
            <div>
              <div style={ST.infoLabel}>Location</div>
              <div style={ST.infoSub}>Location of your database and content</div>
              <div style={ST.infoValue}>
                {region ? `${region.flag} ${region.label}` : app.app_data}
              </div>
            </div>
          </div>


        
        <div style={ST.infoRow}>
          <span style={ST.infoMeta}>Created</span>
          <span style={ST.infoMetaVal}>{formatDate(app.app_date_insert)}</span>
        </div>
        <div style={{ ...ST.infoRow, marginBottom:8 }}>
          <span style={ST.infoMeta}>App ID</span>
          <span style={{ ...ST.infoMetaVal, fontFamily:'DM Mono, monospace', fontSize:11 }}>
            {app.app_id}
          </span>
        </div>
        <AppStats app={app} />
      </div>

      {/* Recent Activity */}
      <div style={ST.card}>
        <div style={ST.cardHeader}>Recent Activity</div>
        <RecentActivity app={app} onViewAll={() => onSwitchTab('logs')} />
      </div>

      {showDomainModal && (
        <CustomDomainModal
          appId={app.app_id}
          cnameTarget={CNAME_TARGET}
          onClose={() => setShowDomainModal(false)}
        />
      )}

    </div>
  );
}

// ── Users tab (stub) ─────────────────────────
function UsersTab({ app, jwt }) {
  return <ComingSoon label="Users" />;
}

// ── Main component ───────────────────────────
function DEVAppDetail({ jwt, currentUser, app, onBack, onAppUpdate }) {
  const [tab, setTab] = React.useState('app');

  return (
    <div>
      {/* Page header */}
      <div style={SD.header}>
        <div style={SD.breadcrumb}>
          <button style={SD.backLink} onClick={onBack}>Apps</button>
          <span style={SD.sep}>/</span>
          <span style={SD.current}>{app.app_name}</span>
        </div>
      </div>

      {/* Tab bar */}
      <div style={SD.tabBar}>
        {TABS.map(t => (
          <button key={t.id} style={{ ...SD.tab, ...(tab === t.id ? SD.tabActive : {}) }}
            onClick={() => setTab(t.id)}>
            {t.label}
          </button>
        ))}
      </div>

      {/* Tab content */}
      <div style={SD.content}>
        {tab === 'app'      && <AppTab app={app} jwt={jwt} onAppUpdate={onAppUpdate} onSwitchTab={setTab} />}
        {tab === 'database' && <DEVDatabase app={app} jwt={jwt}  onAppUpdate={onAppUpdate} onSwitchTab={setTab}/>}
        {tab === 'design'   && <DEVDesign app={app} jwt={jwt} />}
        {tab === 'users'    && <DEVUsers app={app} jwt={jwt} />}
        {tab === 'security' && <DEVSecurity app={app} />}
        {tab === 'logs'     && <DEVLogs app={app} />}
        {tab === 'api'      && <DEVAppAPI app={app} jwt={jwt} />}
      </div>
    </div>
  );
}

// ── Styles ────────────────────────────────────
const SD = {
  header:    { marginBottom:20 },
  breadcrumb:{ display:'flex', alignItems:'center', gap:8 },
  backLink:  { background:'none', border:'none', color:'#2563eb', fontSize:'1rem',
               fontWeight:500, cursor:'pointer', padding:0, fontFamily:'inherit' },
  sep:       { color:'#cbd5e1', fontSize:16 },
  current:   { fontSize:'1rem', fontWeight:600, color:'#0f1923' },
  tabBar:    { display:'flex', borderBottom:'2px solid #e2e8f0', marginBottom:28, gap:0 },
  tab:       { background:'none', border:'none', borderBottom:'2px solid transparent',
               padding:'10px 18px', fontSize:'1rem', fontWeight:500, color:'#64748b',
               cursor:'pointer', fontFamily:'inherit', marginBottom:'-2px',
               transition:'color 0.15s, border-color 0.15s' },
  tabActive: { color:'#0f1923', borderBottomColor:'#0f1923' },
  content:   { },
};

const ST = {
  grid:       { display:'grid', gridTemplateColumns:'repeat(auto-fill, minmax(300px, 1fr))', gap:20 },
  card:       { background:'#fff', borderRadius:12, border:'1px solid #e2e8f0', padding:'22px 24px' },
  cardHeader: { fontSize:13, fontWeight:700, color:'#0f1923', letterSpacing:'0.03em',
                textTransform:'uppercase', marginBottom:18, paddingBottom:12,
                borderBottom:'1px solid #f1f5f9' },
  label:      { display:'block', fontSize:12, fontWeight:500, color:'#64748b', marginBottom:5 },
  optional:   { color:'#94a3b8', fontWeight:400 },
  input:      { width:'100%', padding:'9px 12px', border:'1.5px solid #e2e8f0', borderRadius:7,
                fontSize:13, fontFamily:'DM Sans, sans-serif', outline:'none', marginBottom:14,
                color:'#0f1923', background:'#fff' },
  toggleRow:  { display:'flex', alignItems:'center', justifyContent:'space-between',
                padding:'14px 0', borderTop:'1px solid #f1f5f9', marginBottom:14, gap:12 },
  toggleRowTop:{ display:'flex', alignItems:'center', justifyContent:'space-between',
                padding:'0 0 16px', marginBottom:16, gap:12,
                borderBottom:'1px solid #f1f5f9' },
  addOnBtn:   { background:'#fff', color:'#2563eb', border:'1.5px solid #bfdbfe',
                borderRadius:7, padding:'7px 14px', fontSize:12, fontWeight:600,
                cursor:'pointer', fontFamily:'DM Sans, sans-serif', marginTop:6 },
  toggleLabel:{ fontSize:13, fontWeight:600, color:'#0f1923', marginBottom:3 },
  toggleSub:  { fontSize:11, color:'#94a3b8', lineHeight:1.4 },
  toggleTrack: (on) => ({
    position:'relative', width:44, height:24, borderRadius:12, cursor:'pointer',
    background: on ? '#16a34a' : '#cbd5e1', transition:'background 0.2s', flexShrink:0,
  }),
  toggleThumb: (on) => ({
    position:'absolute', top:3, left: on ? 23 : 3, width:18, height:18,
    borderRadius:9, background:'#fff', boxShadow:'0 1px 3px rgba(0,0,0,0.25)',
    transition:'left 0.2s',
  }),
  saveBtn:    { background:'#0f1923', color:'#fff', border:'none', borderRadius:7,
                padding:'9px 22px', fontSize:13, fontWeight:600, cursor:'pointer',
                fontFamily:'DM Sans, sans-serif', margin:'4px 0px '},
  error:      { background:'#fef2f2', color:'#dc2626', padding:'10px 12px',
                borderRadius:7, fontSize:12, marginBottom:14, border:'1px solid #fecaca' },
  infoBlock:  { display:'flex', gap:12, alignItems:'flex-start', marginBottom:16,
                padding:'12px 0', borderTop:'1px solid #f1f5f9' },
  infoIcon:   { fontSize:18, marginTop:2 },
  infoLabel:  { fontSize:13, fontWeight:600, color:'#0f1923', marginBottom:2 },
  infoSub:    { fontSize:11, color:'#94a3b8', marginBottom:4 },
  infoLink:   { fontSize:12, color:'#2563eb', fontFamily:'DM Mono, monospace',
                textDecoration:'none', wordBreak:'break-all' },
  infoValue:  { fontSize:13, color:'#374151' },
  infoRow:    { display:'flex', justifyContent:'space-between', alignItems:'center',
                padding:'7px 0', borderTop:'1px solid #f8fafc' },
  infoMeta:   { fontSize:12, color:'#94a3b8' },
  infoMetaVal:{ fontSize:12, color:'#374151' },
  statRow:    { display:'flex', justifyContent:'space-between', alignItems:'center',
                padding:'9px 0', borderBottom:'1px solid #f8fafc' },
  statLabel:  { fontSize:13, color:'#64748b' },
  statVal:    { fontSize:13, fontWeight:600, color:'#0f1923' },
  apiNote:    { fontSize:12, color:'#94a3b8', marginBottom:16, lineHeight:1.5 },
  activityRow:  { display:'flex', alignItems:'flex-start', gap:10, padding:'7px 0',
                  borderBottom:'1px solid #f8fafc' },
  activityTime: { fontSize:11, color:'#94a3b8', whiteSpace:'nowrap', minWidth:52, marginTop:2 },
  activityEmail:{ fontSize:12, fontWeight:500, color:'#0f1923' },
  activityMeta: { fontSize:11, color:'#94a3b8' },
  viewAllBtn:   { background:'none', border:'none', color:'#2563eb', fontSize:12, fontWeight:500,
                  cursor:'pointer', padding:'8px 0 0', fontFamily:'DM Sans, sans-serif' },
};

// ── Modal styles (DO Add-On modal shell) ──────
const MD = {
  overlay: { position:'fixed', inset:0, background:'rgba(15,25,35,0.45)',
             display:'flex', alignItems:'center', justifyContent:'center',
             zIndex:1000, padding:20 },
  modal:   { background:'#fff', borderRadius:14, width:'100%', maxWidth:480,
             boxShadow:'0 20px 50px rgba(0,0,0,0.25)', maxHeight:'90vh',
             display:'flex', flexDirection:'column', overflow:'hidden',
             fontFamily:'DM Sans, sans-serif' },
  head:    { display:'flex', alignItems:'center', justifyContent:'space-between',
             padding:'18px 22px', borderBottom:'1px solid #f1f5f9' },
  title:   { fontSize:16, fontWeight:700, color:'#0f1923' },
  close:   { background:'none', border:'none', fontSize:24, lineHeight:1, color:'#94a3b8',
             cursor:'pointer', padding:0, width:28, height:28 },
  body:    { padding:'20px 22px', overflowY:'auto' },
  lead:    { fontSize:13, color:'#374151', lineHeight:1.6, margin:'0 0 18px' },
  code:    { background:'#f1f5f9', padding:'1px 6px', borderRadius:4,
             fontFamily:'DM Mono, monospace', fontSize:12, color:'#0f1923' },
  stepLabel:{ fontSize:11, fontWeight:700, color:'#94a3b8', letterSpacing:'0.05em',
             textTransform:'uppercase', marginBottom:8 },
  steps:   { margin:0, padding:'0 0 0 18px', fontSize:13, color:'#374151', lineHeight:1.7 },
  cnameBox:{ display:'flex', alignItems:'center', gap:8, marginTop:8,
             background:'#f8fafc', border:'1px solid #e2e8f0', borderRadius:7,
             padding:'8px 10px' },
  cnameTarget:{ flex:1, fontFamily:'DM Mono, monospace', fontSize:13, color:'#0f1923' },
  copyBtn: { background:'#0f1923', color:'#fff', border:'none', borderRadius:5,
             padding:'5px 12px', fontSize:11, fontWeight:600, cursor:'pointer',
             fontFamily:'DM Sans, sans-serif', whiteSpace:'nowrap' },
  comingSoon:{ marginTop:18, background:'#fffbeb', border:'1px solid #fde68a',
             borderRadius:8, padding:'12px 14px', fontSize:12.5, color:'#92400e',
             lineHeight:1.5 },
  foot:    { display:'flex', justifyContent:'flex-end', gap:10,
             padding:'16px 22px', borderTop:'1px solid #f1f5f9' },
  btnGhost:{ background:'#fff', color:'#475569', border:'1.5px solid #e2e8f0',
             borderRadius:7, padding:'9px 18px', fontSize:13, fontWeight:600,
             cursor:'pointer', fontFamily:'DM Sans, sans-serif' },
  btnPrimaryDisabled:{ background:'#e2e8f0', color:'#94a3b8', border:'none',
             borderRadius:7, padding:'9px 18px', fontSize:13, fontWeight:600,
             cursor:'not-allowed', fontFamily:'DM Sans, sans-serif' },
};
