/* global React, Icon, fmtRp */
const { useState: useStateCT, useEffect: useEffectCT, useMemo: useMemoCT } = React;

/* =========================================================
 * KONTAK (Customer & Vendor master)
 * ========================================================= */
function ContactsPage() {
  const [tab, setTab] = useStateCT('customer');
  const [list, setList] = useStateCT([]);
  const [loading, setLoading] = useStateCT(true);
  const [search, setSearch] = useStateCT('');
  const [createOpen, setCreateOpen] = useStateCT(false);
  const [editTarget, setEditTarget] = useStateCT(null);

  const load = async () => {
    setLoading(true);
    const q = new URLSearchParams({ kind: tab });
    if (search) q.set('q', search);
    const r = await window.Api.get(`/api/contacts?${q.toString()}`);
    setList(r.data || []);
    setLoading(false);
  };
  useEffectCT(() => { load(); /* eslint-disable-next-line */ }, [tab, search]);

  const removeContact = async (c) => {
    if (!confirm(`Hapus ${c.name}?`)) return;
    try {
      await window.Api.del(`/api/contacts/${encodeURIComponent(c.id)}`);
      load();
    } catch (e) { alert(e.message); }
  };

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Kontak</h1>
          <p className="page-sub">Master data Customer (untuk B2B/reseller) dan Vendor (supplier material)</p>
        </div>
        <div className="page-actions">
          <button className="btn btn-secondary"><Icon.download/> Ekspor</button>
          <button className="btn btn-primary" onClick={() => setCreateOpen(true)}><Icon.plus/> Kontak Baru</button>
        </div>
      </div>

      <div className="tabs">
        <button className={`tab ${tab==='customer'?'active':''}`} onClick={()=>setTab('customer')}>
          Customer<span className="count">{tab==='customer' ? list.length : ''}</span>
        </button>
        <button className={`tab ${tab==='vendor'?'active':''}`} onClick={()=>setTab('vendor')}>
          Vendor<span className="count">{tab==='vendor' ? list.length : ''}</span>
        </button>
      </div>

      <div className="card" style={{ marginBottom:14, padding:'12px 14px' }}>
        <div className="input" style={{ flex:1 }}>
          <Icon.search/>
          <input placeholder={`Cari ${tab === 'customer' ? 'customer' : 'vendor'}…`} value={search} onChange={e=>setSearch(e.target.value)}/>
        </div>
      </div>

      <div className="card" style={{ overflow:'hidden' }}>
        {loading && <div style={{ padding:24, textAlign:'center', color:'var(--ink-500)' }}>Memuat…</div>}
        {!loading && (
          <table className="table">
            <thead>
              <tr>
                <th>Nama</th>
                <th>Kontak Person</th>
                <th>Telp / Email</th>
                <th>Alamat</th>
                <th>NPWP</th>
                {tab === 'vendor' && <th style={{ textAlign:'right' }}>Termin (hari)</th>}
                <th></th>
              </tr>
            </thead>
            <tbody>
              {list.length === 0 && (
                <tr><td colSpan="7" style={{ padding:40, textAlign:'center', color:'var(--ink-500)' }}>
                  Belum ada {tab === 'customer' ? 'customer' : 'vendor'}. Klik <strong>Kontak Baru</strong> untuk menambah.
                </td></tr>
              )}
              {list.map(c => (
                <tr key={c.id} style={{ cursor:'pointer' }} onClick={() => setEditTarget(c)}>
                  <td>
                    <div style={{ fontWeight:600 }}>{c.name}</div>
                    {c.code && <div style={{ fontSize:11, color:'var(--ink-500)', fontFamily:'monospace' }}>{c.code}</div>}
                  </td>
                  <td>{c.contactPerson || '—'}</td>
                  <td>
                    {c.phone && <div style={{ fontSize:13 }}>{c.phone}</div>}
                    {c.email && <div style={{ fontSize:11.5, color:'var(--ink-500)' }}>{c.email}</div>}
                    {!c.phone && !c.email && '—'}
                  </td>
                  <td style={{ fontSize:12, color:'var(--ink-700)', maxWidth:300 }}>{c.address || '—'}</td>
                  <td><span className="mono" style={{ fontSize:11 }}>{c.npwp || '—'}</span></td>
                  {tab === 'vendor' && (
                    <td style={{ textAlign:'right' }}>{c.paymentTerms != null ? `${c.paymentTerms} hari` : '—'}</td>
                  )}
                  <td style={{ textAlign:'right' }}>
                    <div style={{ display:'inline-flex', gap:6 }}>
                      <button className="btn btn-secondary btn-sm" onClick={(e)=>{ e.stopPropagation(); setEditTarget(c); }}>Edit</button>
                      <button className="btn btn-secondary btn-sm" onClick={(e)=>{ e.stopPropagation(); removeContact(c); }}>Hapus</button>
                    </div>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        )}
      </div>

      {createOpen && <ContactModal initialKind={tab} onClose={() => setCreateOpen(false)} onSaved={load}/>}
      {editTarget && <ContactModal contact={editTarget} initialKind={tab} onClose={() => setEditTarget(null)} onSaved={load}/>}
    </div>
  );
}

function ContactModal({ contact, initialKind, onClose, onSaved }) {
  const isEdit = !!contact;
  const [data, setData] = useStateCT(() => contact || {
    kind: initialKind || 'customer',
    name: '', code: '', contactPerson: '', email: '', phone: '',
    address: '', npwp: '', paymentTerms: '', notes: '',
  });
  const [busy, setBusy] = useStateCT(false);
  const [error, setError] = useStateCT('');

  const update = (k, v) => setData({ ...data, [k]: v });

  const submit = async (e) => {
    e.preventDefault();
    setError('');
    setBusy(true);
    try {
      const payload = {
        kind: data.kind,
        name: data.name,
        code: data.code || undefined,
        contactPerson: data.contactPerson || undefined,
        email: data.email || undefined,
        phone: data.phone || undefined,
        address: data.address || undefined,
        npwp: data.npwp || undefined,
        paymentTerms: data.paymentTerms ? Number(data.paymentTerms) : undefined,
        notes: data.notes || undefined,
      };
      if (isEdit) {
        await window.Api.patch(`/api/contacts/${encodeURIComponent(contact.id)}`, payload);
      } else {
        await window.Api.post('/api/contacts', payload);
      }
      await onSaved();
      onClose();
    } catch (err) {
      setError(err.body?.message || err.message || 'Gagal');
      setBusy(false);
    }
  };

  return (
    <div className="modal-backdrop" onClick={onClose}>
      <div className="modal" style={{ maxWidth:620 }} onClick={e=>e.stopPropagation()}>
        <div className="modal-head">
          <div>
            <div style={{ fontSize:11, fontWeight:700, textTransform:'uppercase', letterSpacing:'.06em', color:'var(--ink-500)' }}>
              {isEdit ? 'Edit Kontak' : 'Kontak Baru'}
            </div>
            <h2 style={{ margin:'4px 0 0', fontSize:20, fontWeight:800 }}>{data.name || (data.kind === 'vendor' ? 'Vendor baru' : 'Customer baru')}</h2>
          </div>
          <button className="tb-icon-btn" onClick={onClose}><Icon.x/></button>
        </div>
        <form onSubmit={submit} style={{ padding:'20px 22px', display:'flex', flexDirection:'column', gap:14 }}>
          {error && <div style={{ padding:'10px 14px', background:'#fee2e2', color:'#991b1b', borderRadius:8, fontSize:13 }}>{error}</div>}

          <FieldCT label="Tipe">
            <div style={{ display:'flex', gap:8 }}>
              {['customer', 'vendor', 'both'].map(k => (
                <button key={k} type="button"
                  className={`pick ${data.kind === k ? 'on' : ''}`}
                  onClick={() => update('kind', k)}
                  style={{ flex:1 }}
                >
                  {k === 'customer' ? 'Customer' : k === 'vendor' ? 'Vendor' : 'Customer + Vendor'}
                </button>
              ))}
            </div>
          </FieldCT>

          <div style={{ display:'grid', gridTemplateColumns:'1fr 200px', gap:12 }}>
            <FieldCT label="Nama *">
              <input className="input" value={data.name} onChange={e=>update('name', e.target.value)} required/>
            </FieldCT>
            <FieldCT label="Kode internal (opsional)">
              <input className="input" value={data.code || ''} onChange={e=>update('code', e.target.value)} placeholder="CUS-001"/>
            </FieldCT>
          </div>

          <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:12 }}>
            <FieldCT label="Kontak person">
              <input className="input" value={data.contactPerson || ''} onChange={e=>update('contactPerson', e.target.value)}/>
            </FieldCT>
            <FieldCT label="No. telp / WhatsApp">
              <input className="input" value={data.phone || ''} onChange={e=>update('phone', e.target.value)}/>
            </FieldCT>
            <FieldCT label="Email">
              <input className="input" type="email" value={data.email || ''} onChange={e=>update('email', e.target.value)}/>
            </FieldCT>
            <FieldCT label="NPWP">
              <input className="input" value={data.npwp || ''} onChange={e=>update('npwp', e.target.value)}/>
            </FieldCT>
          </div>

          <FieldCT label="Alamat">
            <textarea className="input" rows="2" value={data.address || ''} onChange={e=>update('address', e.target.value)}/>
          </FieldCT>

          {(data.kind === 'vendor' || data.kind === 'both') && (
            <FieldCT label="Termin pembayaran (hari)">
              <input className="input" type="number" min="0" value={data.paymentTerms || ''} onChange={e=>update('paymentTerms', e.target.value)} placeholder="30"/>
            </FieldCT>
          )}

          <FieldCT label="Catatan">
            <textarea className="input" rows="2" value={data.notes || ''} onChange={e=>update('notes', e.target.value)}/>
          </FieldCT>

          <div className="modal-foot" style={{ margin:'4px -22px -20px' }}>
            <button type="button" className="btn btn-secondary" onClick={onClose} disabled={busy}>Batal</button>
            <button type="submit" className="btn btn-primary" disabled={busy}>{busy ? 'Menyimpan…' : (isEdit ? 'Simpan Perubahan' : 'Simpan Kontak')}</button>
          </div>
        </form>
      </div>
    </div>
  );
}

/* =========================================================
 * AGING REPORT — Piutang & Hutang
 * ========================================================= */
function AgingReportPage() {
  const [tab, setTab] = useStateCT('ar');
  const [data, setData] = useStateCT(null);
  const [loading, setLoading] = useStateCT(true);
  const [openBucket, setOpenBucket] = useStateCT(null);

  const load = async () => {
    setLoading(true);
    const path = tab === 'ar' ? '/api/aging/receivables' : '/api/aging/payables';
    const r = await window.Api.get(path);
    setData(r.data);
    setLoading(false);
  };
  useEffectCT(() => { load(); setOpenBucket(null); /* eslint-disable-next-line */ }, [tab]);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Aging Report</h1>
          <p className="page-sub">Piutang (AR) & Hutang (AP) yang belum dilunasi, dikelompokkan per umur</p>
        </div>
      </div>

      <div className="tabs">
        <button className={`tab ${tab==='ar'?'active':''}`} onClick={()=>setTab('ar')}>Piutang Customer (AR)</button>
        <button className={`tab ${tab==='ap'?'active':''}`} onClick={()=>setTab('ap')}>Hutang Vendor (AP)</button>
      </div>

      {loading && <div className="card" style={{ padding:24, textAlign:'center', color:'var(--ink-500)' }}>Memuat…</div>}

      {!loading && data && (
        <>
          <div className="card" style={{ marginBottom:18, padding:'24px 28px', background:'linear-gradient(135deg, var(--brand-50), white)' }}>
            <div style={{ fontSize:13, color:'var(--ink-600)', fontWeight:600, textTransform:'uppercase', letterSpacing:'.04em' }}>
              Total {tab === 'ar' ? 'Piutang Outstanding' : 'Hutang Belum Lunas'}
            </div>
            <div style={{ fontSize:40, fontWeight:800, marginTop:6, fontFeatureSettings:'"tnum"' }}>{fmtRp(data.totalOutstanding)}</div>
            <div style={{ fontSize:13, color:'var(--ink-500)', marginTop:6 }}>
              <strong>{data.totalCount}</strong> {tab === 'ar' ? 'pesanan' : 'PO'} per {data.asOf}
            </div>
          </div>

          <div className="grid-4" style={{ gridTemplateColumns:'repeat(5, 1fr)', marginBottom:18, gap:8 }}>
            {data.buckets.map((b, idx) => {
              const isOpen = openBucket === b.key;
              const tone = idx === 0 ? 'green' : idx <= 2 ? 'amber' : 'rose';
              return (
                <BucketCard
                  key={b.key}
                  label={b.label}
                  count={b.count}
                  total={b.total}
                  tone={tone}
                  active={isOpen}
                  onClick={() => setOpenBucket(isOpen ? null : b.key)}
                />
              );
            })}
          </div>

          {openBucket && (
            <div className="card" style={{ overflow:'hidden' }}>
              <div className="card-header">
                <div>
                  <h3 className="card-title">{data.buckets.find(b => b.key === openBucket)?.label}</h3>
                  <p className="card-sub">{data.buckets.find(b => b.key === openBucket)?.count} item · klik bucket lain untuk ganti</p>
                </div>
              </div>
              <table className="table">
                <thead>
                  <tr>
                    {tab === 'ar' ? (
                      <>
                        <th>Pesanan</th>
                        <th>Sumber</th>
                        <th>Pembeli</th>
                        <th>Status</th>
                        <th style={{ textAlign:'right' }}>Umur</th>
                        <th style={{ textAlign:'right' }}>Telat</th>
                        <th style={{ textAlign:'right' }}>Nilai</th>
                      </>
                    ) : (
                      <>
                        <th>No. PO</th>
                        <th>Vendor</th>
                        <th>Tgl PO</th>
                        <th>Jatuh Tempo</th>
                        <th style={{ textAlign:'right' }}>Telat</th>
                        <th style={{ textAlign:'right' }}>Nilai</th>
                      </>
                    )}
                  </tr>
                </thead>
                <tbody>
                  {data.buckets.find(b => b.key === openBucket).items.map((it) => (
                    <tr key={it.id}>
                      <td><span className="mono">{it.id}</span></td>
                      {tab === 'ar' ? (
                        <>
                          <td>{it.source}</td>
                          <td>{it.buyerName}</td>
                          <td><span className="chip">{it.status}</span></td>
                          <td style={{ textAlign:'right' }}>{it.daysOld} hari</td>
                          <td style={{ textAlign:'right', fontWeight:700, color: it.daysOverdue > 0 ? 'var(--rose)' : 'var(--ink-500)' }}>
                            {it.daysOverdue > 0 ? `${it.daysOverdue} hari` : '—'}
                          </td>
                        </>
                      ) : (
                        <>
                          <td>{it.vendor}</td>
                          <td style={{ fontSize:13 }}>{it.poDate}</td>
                          <td style={{ fontSize:13 }}>{it.dueDate || '—'}</td>
                          <td style={{ textAlign:'right', fontWeight:700, color: it.daysOverdue > 0 ? 'var(--rose)' : 'var(--ink-500)' }}>
                            {it.daysOverdue > 0 ? `${it.daysOverdue} hari` : '—'}
                          </td>
                        </>
                      )}
                      <td style={{ textAlign:'right', fontWeight:700 }}>{fmtRp(it.amount)}</td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          )}
        </>
      )}
    </div>
  );
}

function BucketCard({ label, count, total, tone, active, onClick }) {
  const colors = { green:'var(--green)', amber:'var(--amber)', rose:'var(--rose)' };
  return (
    <div className="card" onClick={onClick} style={{
      padding:'14px 16px', cursor:'pointer',
      border: active ? `2px solid ${colors[tone]}` : undefined,
      background: active ? `${colors[tone]}14` : undefined,
    }}>
      <div style={{ fontSize:11, color:'var(--ink-500)', fontWeight:600, textTransform:'uppercase', letterSpacing:'.04em' }}>{label}</div>
      <div style={{ fontSize:20, fontWeight:800, marginTop:4, color: count > 0 ? colors[tone] : 'var(--ink-400)' }}>
        {fmtRp(total)}
      </div>
      <div style={{ fontSize:11, color:'var(--ink-500)', marginTop:2 }}>{count} item</div>
    </div>
  );
}

function FieldCT({ label, children }) {
  return (
    <label style={{ display:'flex', flexDirection:'column', gap:6 }}>
      <span style={{ fontSize:12, fontWeight:600, color:'var(--ink-700)' }}>{label}</span>
      {children}
    </label>
  );
}

/* =========================================================
 * AUDIT LOG (Owner only)
 * ========================================================= */
const ACTION_LABELS = {
  create: { label: 'Bikin', color: 'var(--green)' },
  update: { label: 'Ubah', color: 'var(--blue)' },
  delete: { label: 'Hapus', color: 'var(--rose)' },
  post: { label: 'Posting', color: 'var(--brand-500)' },
  reverse: { label: 'Pembalik', color: 'var(--rose)' },
  status_change: { label: 'Ubah Status', color: 'var(--blue)' },
  approve: { label: 'Setujui', color: 'var(--green)' },
  receive: { label: 'Terima', color: 'var(--green)' },
  intake: { label: 'Intake', color: 'var(--brand-500)' },
  adjust: { label: 'Koreksi', color: 'var(--amber)' },
  role_switch: { label: 'Ganti Peran', color: 'var(--blue)' },
  auto_run: { label: 'Auto-jalan', color: 'var(--brand-500)' },
};

const ENTITY_LABELS = {
  journal: 'Jurnal',
  order: 'Pesanan',
  product: 'Produk',
  inventory: 'Stok',
  contact: 'Kontak',
  opname: 'Stock Opname',
  po: 'PO Material',
  return: 'Retur',
  profile: 'Profil',
  recurring: 'Jurnal Berulang',
};

function AuditLogPage() {
  const [list, setList] = useStateCT([]);
  const [loading, setLoading] = useStateCT(true);
  const [action, setAction] = useStateCT('');
  const [entity, setEntity] = useStateCT('');
  const [from, setFrom] = useStateCT('');
  const [to, setTo] = useStateCT('');

  const load = async () => {
    setLoading(true);
    const q = new URLSearchParams();
    if (action) q.set('action', action);
    if (entity) q.set('entity', entity);
    if (from) q.set('from', from);
    if (to) q.set('to', to);
    try {
      const r = await window.Api.get(`/api/audit?${q.toString()}`);
      setList(r.data || []);
    } catch (e) {
      console.error(e);
      setList([]);
    } finally { setLoading(false); }
  };
  useEffectCT(() => { load(); /* eslint-disable-next-line */ }, [action, entity, from, to]);

  return (
    <div className="page">
      <div className="page-head">
        <div>
          <h1 className="page-title">Audit Log</h1>
          <p className="page-sub">Riwayat seluruh perubahan data — siapa, kapan, dan apa yang diubah. Hanya Owner yang bisa lihat.</p>
        </div>
        <div className="page-actions">
          <window.DateRangeFilter from={from} to={to} onChange={({ from, to }) => { setFrom(from); setTo(to); }}/>
        </div>
      </div>

      <div className="card" style={{ marginBottom:14, padding:'12px 14px', display:'flex', gap:10 }}>
        <div className="input" style={{ width:200 }}>
          <select value={action} onChange={e=>setAction(e.target.value)}>
            <option value="">Semua aksi</option>
            {Object.entries(ACTION_LABELS).map(([k, v]) => (
              <option key={k} value={k}>{v.label}</option>
            ))}
          </select>
        </div>
        <div className="input" style={{ width:200 }}>
          <select value={entity} onChange={e=>setEntity(e.target.value)}>
            <option value="">Semua entitas</option>
            {Object.entries(ENTITY_LABELS).map(([k, v]) => (
              <option key={k} value={k}>{v}</option>
            ))}
          </select>
        </div>
        <button className="btn btn-secondary" onClick={() => { setAction(''); setEntity(''); setFrom(''); setTo(''); }}>Reset</button>
        <div style={{ marginLeft:'auto', fontSize:12, color:'var(--ink-500)', alignSelf:'center' }}>
          {list.length} entries · max 500 per page
        </div>
      </div>

      <div className="card" style={{ overflow:'hidden' }}>
        {loading && <div style={{ padding:24, textAlign:'center', color:'var(--ink-500)' }}>Memuat…</div>}
        {!loading && (
          <table className="table">
            <thead>
              <tr>
                <th>Waktu</th>
                <th>Aktor</th>
                <th>Aksi</th>
                <th>Entitas</th>
                <th>Deskripsi</th>
                <th>IP</th>
              </tr>
            </thead>
            <tbody>
              {list.length === 0 && (
                <tr><td colSpan="6" style={{ padding:40, textAlign:'center', color:'var(--ink-500)' }}>
                  Tidak ada log dengan filter ini.
                </td></tr>
              )}
              {list.map(log => {
                const am = ACTION_LABELS[log.action] || { label: log.action, color: 'var(--ink-500)' };
                const em = ENTITY_LABELS[log.entity] || log.entity;
                return (
                  <tr key={log.id}>
                    <td style={{ fontSize:12, fontFamily:'monospace', whiteSpace:'nowrap' }}>
                      {new Date(log.createdAt).toLocaleString('id-ID', { dateStyle: 'short', timeStyle: 'medium' })}
                    </td>
                    <td>
                      <div style={{ fontSize:13, fontWeight:600 }}>{log.actorEmail || '—'}</div>
                      {log.actorRole && log.actorRole !== 'system' && (
                        <span className="chip" style={{ fontSize:10 }}>{log.actorRole}</span>
                      )}
                    </td>
                    <td>
                      <span className="chip" style={{ background:`${am.color}1a`, color:am.color, fontSize:11 }}>
                        {am.label}
                      </span>
                    </td>
                    <td>
                      <strong style={{ fontSize:13 }}>{em}</strong>
                      {log.entityId && (
                        <div className="mono" style={{ fontSize:11, color:'var(--ink-500)' }}>{log.entityId}</div>
                      )}
                    </td>
                    <td style={{ fontSize:13 }}>
                      {log.description || '—'}
                      {log.meta && Object.keys(log.meta).length > 0 && (
                        <details style={{ marginTop:4 }}>
                          <summary style={{ fontSize:11, color:'var(--ink-500)', cursor:'pointer' }}>meta</summary>
                          <pre style={{ fontSize:10.5, color:'var(--ink-700)', background:'var(--surface-2)', padding:6, borderRadius:6, marginTop:4, maxWidth:400, overflow:'auto' }}>
{JSON.stringify(log.meta, null, 2)}
                          </pre>
                        </details>
                      )}
                    </td>
                    <td style={{ fontSize:11, color:'var(--ink-500)', fontFamily:'monospace' }}>{log.ipAddress || '—'}</td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        )}
      </div>
    </div>
  );
}

window.ContactsPage = ContactsPage;
window.AgingReportPage = AgingReportPage;
window.AuditLogPage = AuditLogPage;
