/* =========================================================================
   MIZUONE — ALUR TOPUP KARTU (kartu fisik + chip)
   ========================================================================= */
/* hooks & komponen bersama berasal dari aq-core.jsx (scope global) */
const kWrap = "max-w-lg sm:max-w-xl mx-auto";

/* Visual kartu fisik — gambar Kota Malang + eye toggle nomor kartu */
function PhysicalCard({ saldo, cardNo, mini=false }){
  const [showNo, setShowNo] = React.useState(false);
  const tail = cardNo ? String(cardNo).slice(-4) : '????';
  const fullNo = cardNo ? String(cardNo).replace(/(.{4})/g,'$1 ').trim() : '';
  const maskedNo = `•••• •••• •• ${tail}`;

  const EyeOn = ()=>(
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-4 h-4">
      <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z"/><circle cx="12" cy="12" r="3"/>
    </svg>
  );
  const EyeOff = ()=>(
    <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="w-4 h-4">
      <path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19m-6.72-1.07a3 3 0 11-4.24-4.24"/>
      <line x1="1" y1="1" x2="23" y2="23"/>
    </svg>
  );

  return (
    <div className={"relative overflow-hidden rounded-2xl shadow-soft "+(mini?'h-20 flex-shrink-0':'')}>
      {mini
        ? <img src={imgSrc('kartu-mizuone-physical.jpeg')} alt="Kartu MizuOne" className="absolute inset-0 w-full h-full object-cover"/>
        : <img src={imgSrc('kartu-mizuone-physical.jpeg')} alt="Kartu MizuOne" className="w-full h-auto block"/>
      }

      {/* Overlay bawah untuk teks */}
      <div className={"absolute inset-x-0 bottom-0 bg-gradient-to-t from-black/75 via-black/40 to-transparent px-4 pt-8 pb-4"}>
        {!mini && (
          <div className="flex items-center justify-between mb-1.5">
            <span className="font-mono tracking-[.18em] text-white text-sm drop-shadow">
              {showNo ? fullNo : maskedNo}
            </span>
            <button
              onClick={()=>setShowNo(s=>!s)}
              className="w-8 h-8 rounded-full bg-white/20 backdrop-blur-sm flex items-center justify-center text-white active:scale-90 transition shrink-0 ml-2"
              aria-label={showNo?'Sembunyikan nomor':'Tampilkan nomor'}>
              {showNo ? <EyeOff/> : <EyeOn/>}
            </button>
          </div>
        )}
        <div className="flex items-end justify-between">
          <div>
            <div className="text-white/70 text-[10px] uppercase tracking-wide font-bold">Saldo Kartu</div>
            <div className={"font-extrabold text-white tabular-nums drop-shadow "+(mini?'text-lg':'text-2xl')}>
              {saldo!=null ? fmtRp(saldo) : '—'}
            </div>
          </div>
          {mini && <div className="font-mono text-white/80 text-sm">••{tail}</div>}
        </div>
      </div>
    </div>
  );
}

/* =========================================================================
   KARTU · LOGIN (daftar kartu user / masukkan nomor kartu)
   ========================================================================= */
function KartuLogin({ go, back, onCard }){
  const [manual, setManual] = useState(false);
  const [no, setNo] = useState('');
  const [userCards, setUserCards] = useState(null); // null=loading, []=kosong
  const [cardWarn, setCardWarn] = useState(false);
  const noOk = no.replace(/\D/g,'').length >= 5;

  useEffect(()=>{
    if(!window.AquAPI?.hasToken()){ setUserCards([]); return; }
    window.AquAPI.kartuList()
      .then(r=>setUserCards(r.data || []))
      .catch(()=>setUserCards([]));
  },[]);

  const doSelectCard = (card)=>{
    onCard && onCard(card.nokartu, card.saldo ?? null);
    go('kartu-home');
  };

  const doEnterCard = ()=>{
    const clean = no.replace(/\D/g,'');
    const inList = userCards && userCards.some(c=>String(c.nokartu)===clean);
    if(userCards && userCards.length > 0 && !inList && !cardWarn){
      setCardWarn(true);
      return;
    }
    onCard && onCard(clean, null);
    go('kartu-home');
  };

  return (
    <div className="relative fade-in" data-screen-label="KartuLogin">
      <WaterHeader className="absolute top-0 left-0 right-0 h-44 rounded-b-[2rem]"><div className="h-44"></div></WaterHeader>
      <div className={"relative "+kWrap+" px-4 pt-5 pb-12"}>
        <div className="relative z-10"><ScreenTop onBack={back} title="Kartu MizuOne" light/></div>
        <Card className="p-5 sm:p-6 pop">

          {/* Loading */}
          {userCards === null && (
            <div className="text-center py-6 text-slate-400 text-sm sub">Memuat kartu…</div>
          )}

          {/* Kartu terdaftar di akun */}
          {userCards && userCards.length > 0 && !manual && (
            <div className="fade-in">
              <div className="text-sm font-semibold mb-2">Pilih kartu kamu</div>
              {userCards.map(c=>(
                <button key={c.nokartu} onClick={()=>doSelectCard(c)}
                  className="w-full flex items-center justify-between px-4 py-3 rounded-xl border-2 border-slate-200 dark:border-slate-700 hover:border-mizu/60 hover:bg-mizu-light/30 transition mb-2 active:scale-[.98]">
                  <div className="flex items-center gap-3">
                    <div className="w-9 h-9 rounded-lg bg-mizu-light text-mizu grid place-items-center shrink-0"><Ic.tap className="w-5 h-5"/></div>
                    <div className="text-left">
                      <div className="font-bold font-mono text-sm">•••• {String(c.nokartu).slice(-4)}</div>
                      {c.saldo != null && <div className="text-xs text-slate-500 sub">{fmtRp(c.saldo)}</div>}
                    </div>
                  </div>
                  <Ic.arrow className="w-4 h-4 text-slate-400 shrink-0"/>
                </button>
              ))}
              <button onClick={()=>setManual(true)} className="block w-full text-center mt-3 text-sm font-semibold text-mizu hover:underline">
                Masukkan nomor kartu lain
              </button>
            </div>
          )}

          {/* Manual entry */}
          {userCards !== null && (userCards.length === 0 || manual) && (
            <div className="fade-in">
              {manual && userCards.length > 0 && (
                <button onClick={()=>setManual(false)} className="inline-flex items-center gap-1.5 text-sm font-semibold text-mizu mb-4">
                  <Ic.back className="w-4 h-4"/> Pilih dari daftar
                </button>
              )}
              {!manual && (
                <>
                  <div className="w-12 h-12 rounded-2xl bg-mizu-light text-mizu grid place-items-center mx-auto mb-3"><Ic.tap className="w-6 h-6"/></div>
                  <h2 className="text-xl font-extrabold text-center">Masukkan nomor kartu</h2>
                  <p className="text-slate-500 text-sm mt-1 mb-4 sub text-center">Nomor kartu tertera di bagian belakang kartu fisik MizuOne.</p>
                </>
              )}
              <label className="block">
                <span className="block text-sm font-semibold mb-1.5">Nomor kartu</span>
                <input value={no}
                  onChange={e=>{ setNo(e.target.value.replace(/\D/g,'').slice(0,12)); setCardWarn(false); }}
                  onKeyDown={e=>e.key==='Enter'&&noOk&&doEnterCard()}
                  className={inputCls+" font-mono tracking-widest text-lg"}
                  inputMode="numeric" placeholder="123456789"/>
              </label>
              {cardWarn && (
                <div className="mt-3 flex items-start gap-2 rounded-xl bg-warning/10 border border-warning/30 px-3 py-2.5 text-sm text-[#946200]">
                  <svg className="w-4 h-4 mt-0.5 shrink-0" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="M10.3 3.3 2 19a2 2 0 0 0 1.7 3h16.6A2 2 0 0 0 22 19L13.7 3.3a2 2 0 0 0-3.4 0Z"/><line x1="12" y1="9" x2="12" y2="13"/><line x1="12" y1="17" x2="12.01" y2="17"/></svg>
                  <span>Kartu ini belum terdaftar di akun kamu. Yakin ingin lanjut?</span>
                </div>
              )}
              <Button size="lg" className="w-full mt-5" disabled={!noOk} onClick={doEnterCard} iconRight={<Ic.arrow className="w-5 h-5"/>}>{cardWarn ? 'Lanjut Saja' : 'Masuk'}</Button>
            </div>
          )}

          <hr className="my-5 border-slate-100 dark:border-slate-800"/>
          <button onClick={()=>go('digital')}
            className="w-full flex items-center gap-3 rounded-2xl border-2 border-mizu/25 bg-mizu-light/60 px-4 py-3.5 active:scale-[.98] hover:border-mizu/50 transition text-left">
            <div className="shrink-0 w-10 h-10 rounded-xl bg-mizu text-white grid place-items-center">
              <Ic.wallet className="w-5 h-5"/>
            </div>
            <div className="flex-1 min-w-0">
              <p className="font-bold text-sm text-mizu-700">Tidak punya kartu fisik?</p>
              <p className="text-xs text-slate-500 sub leading-snug mt-0.5">Pakai dompet digital — topup &amp; beli air langsung dari HP, tanpa kartu</p>
            </div>
            <Ic.arrow className="w-4 h-4 text-mizu shrink-0"/>
          </button>
        </Card>
      </div>
    </div>
  );
}

/* =========================================================================
   KARTU · HOME
   ========================================================================= */
function KartuHome({ go, notice, saldo, cardNo }){
  return (
    <div className="fade-in" data-screen-label="KartuHome">
      <WaterHeader className="rounded-b-2xl">
        <div className={kWrap+" px-5 pt-6 pb-10"}>
          <p className="text-white/80 text-sm">Kartu MizuOne</p>
          <h1 className="text-2xl font-extrabold tracking-tight">
            {cardNo ? '•••• ' + String(cardNo).slice(-4) : 'Kartu'}
          </h1>
        </div>
      </WaterHeader>
      <div className={kWrap+" px-4 -mt-8 relative z-10 pb-6"}>
        <div className="pop mx-5"><PhysicalCard saldo={saldo} cardNo={cardNo}/></div>

        <div className="grid grid-cols-2 gap-2.5 mt-4">
          <Button variant="primary" onClick={()=>go('kartu-topup')} icon={<Ic.plus className="w-5 h-5"/>}>Topup Kartu</Button>
          <Button variant="outline" onClick={()=>go('kartu-riwayat')} icon={<Ic.list className="w-5 h-5"/>}>Riwayat</Button>
        </div>

        <Card className="mt-4 p-4 flex items-center gap-3">
          <div className="shrink-0 w-11 h-11 rounded-xl bg-mizu-light text-mizu grid place-items-center"><Ic.tap className="w-6 h-6"/></div>
          <p className="text-sm text-slate-600 dark:text-slate-300 sub">Tap kartu di mesin MizuOne untuk beli air langsung — saldo dipotong otomatis.</p>
        </Card>
      </div>
    </div>
  );
}

/* =========================================================================
   KARTU · TOPUP — pilih nominal → generate QRIS real via backend
   ========================================================================= */
function KartuTopup({ go, back, saldo, cardNo, notice, onTopup }){
  const presets = [10000,25000,50000,100000];
  const [sel, setSel] = useState(50000);
  const [custom, setCustom] = useState('');
  const [busy, setBusy] = useState(false);
  const [err, setErr] = useState('');
  const [qr, setQr] = useState(false);
  const [qrData, setQrData] = useState({ url:null, orderId:null });
  const [phase, setPhase] = useState('pilih'); // pilih | tap
  const [payMethod, setPayMethod] = useState('qris'); // 'qris' | 'digital'
  const [secs, setSecs] = useState(5*60);
  const amount = custom ? (parseInt(custom)||0) : sel;
  const [digSaldo, setDigSaldo] = useState(null);

  // Load saldo digital jika user punya token
  useEffect(()=>{
    if(!(window.AquAPI && window.AquAPI.hasToken())) return;
    window.AquAPI.balance().then(r=>setDigSaldo(r.balance)).catch(()=>{});
  },[]);

  const doPayWithDigital = async ()=>{
    if(amount < 10000){ setErr('Minimal topup Rp 10.000'); return; }
    if(digSaldo != null && amount > digSaldo){ setErr('Saldo digital tidak cukup'); return; }
    setBusy(true); setErr('');
    try {
      const r = await window.AquAPI.transferToCard(cardNo, amount);
      if(r.status === 'success'){
        onTopup && onTopup(amount);
        notice && notice('Transfer berhasil! Kartu sudah dikreditkan.');
        setPayMethod('digital');
        setPhase('tap');
      } else { setErr(r.message || 'Transfer gagal'); }
    } catch(e){ setErr(e.message || 'Gagal transfer'); }
    setBusy(false);
  };

  useEffect(()=>{ if(phase!=='tap')return; if(secs<=0)return; const t=setTimeout(()=>setSecs(s=>s-1),1000); return ()=>clearTimeout(t); },[phase,secs]);
  const mm = String(Math.floor(secs/60)).padStart(2,'0'), ss2 = String(secs%60).padStart(2,'0');

  if(!cardNo){
    return (
      <div className="relative fade-in" data-screen-label="KartuTopup">
        <WaterHeader className="absolute top-0 left-0 right-0 h-44 rounded-b-[2rem]"><div className="h-44"></div></WaterHeader>
        <div className={"relative "+kWrap+" px-4 pt-5 pb-12"}>
          <div className="relative z-10"><ScreenTop onBack={back} title="Topup Kartu" light/></div>
          <Card className="p-6 text-center">
            <p className="text-slate-500 sub">Silakan scan atau masukkan nomor kartu terlebih dahulu.</p>
            <Button size="lg" className="w-full mt-4" onClick={back}>Kembali</Button>
          </Card>
        </div>
      </div>
    );
  }

  const doShowQR = async ()=>{
    if(amount < 10000){ setErr('Minimal topup Rp 10.000'); return; }
    setBusy(true); setErr('');
    try {
      const r = await window.AquAPI.kartuTopup(cardNo, amount);
      if(r.redirect_url){
        setQrData({ url: r.redirect_url, orderId: r.order_id });
        setQr(true);
      } else { setErr('Gagal membuat QRIS'); }
    } catch(e){ setErr(e.message || 'Gagal topup'); }
    setBusy(false);
  };

  return (
    <div className="relative fade-in" data-screen-label="KartuTopup">
      <WaterHeader className="absolute top-0 left-0 right-0 h-44 rounded-b-[2rem]"><div className="h-44"></div></WaterHeader>
      <div className={"relative "+kWrap+" px-4 pt-5 pb-12"}>
        <div className="relative z-10"><ScreenTop onBack={()=> phase==='tap'?setPhase('pilih'):back()} title="Topup Kartu" light/></div>

        {phase==='pilih' ? (
          <Card className="p-5 sm:p-6 pop">
            <PhysicalCard saldo={saldo} cardNo={cardNo} mini/>
            <div className="text-sm font-semibold mt-5 mb-2">Pilih nominal topup</div>
            <div className="grid grid-cols-2 gap-2.5">
              {presets.map(v=>(
                <button key={v} onClick={()=>{setSel(v);setCustom('');setErr('');}}
                  className={"rounded-xl border-2 py-3.5 font-bold text-[15px] tabular-nums transition "+(!custom&&sel===v?'border-mizu bg-mizu-light text-mizu-700':'border-slate-200 dark:border-slate-700 hover:border-mizu/40')}>
                  {fmtRp(v)}
                </button>
              ))}
            </div>
            <label className="block mt-4">
              <span className="block text-sm font-semibold mb-1.5">Jumlah lain</span>
              <div className={"flex items-center rounded-xl border-2 px-3.5 min-h-[52px] transition "+(custom?'border-mizu':'border-slate-200 dark:border-slate-700')}>
                <span className="text-slate-400 font-semibold mr-1">Rp</span>
                <input type="number" inputMode="numeric" min="10000" step="1000" placeholder="0" value={custom}
                  onChange={e=>{setCustom(e.target.value);setErr('');}}
                  className="flex-1 bg-transparent outline-none text-[16px] font-bold tabular-nums placeholder:text-slate-300"/>
              </div>
            </label>
            <div className="mt-5 rounded-xl bg-slate-50 dark:bg-slate-800/60 p-4 flex items-center justify-between">
              <span className="text-sm text-slate-500 sub">Total bayar</span>
              <span className="text-lg font-extrabold text-mizu tabular-nums">{fmtRp(amount)}</span>
            </div>
            <p className="text-xs text-slate-400 mt-2 flex items-center gap-1.5"><Ic.tap className="w-4 h-4"/> Saldo kartu bertambah setelah tap di mesin.</p>
            {err && <p className="text-danger text-sm mt-2 text-center font-semibold">{err}</p>}
            <Button size="lg" className="w-full mt-4" disabled={amount<10000||busy} onClick={doShowQR} icon={<Ic.qr className="w-5 h-5"/>}>
              {busy?'Memproses…':'Bayar via QRIS'}
            </Button>
            {digSaldo != null && digSaldo > 0 && (
              <Button variant="outline" size="lg"
                className={"w-full mt-2.5 "+(amount <= digSaldo ? '!border-success/50 !text-success' : '!border-slate-200 opacity-60')}
                disabled={amount<10000||busy||amount>digSaldo}
                onClick={doPayWithDigital}
                icon={<Ic.wallet className="w-5 h-5"/>}>
                {busy?'Memproses…':`Bayar pakai Saldo Digital (${fmtRp(digSaldo)})`}
              </Button>
            )}
            <p className="text-center text-xs text-slate-400 mt-2.5">Bayar via QRIS Faspay, atau potong langsung dari saldo digitalmu</p>
          </Card>
        ) : (
          <Card className="p-6 text-center pop">
            <Badge tone="success" className="mx-auto">Pembayaran diterima ✓</Badge>
            <img src={imgSrc('mascot-salam.png')} alt="Maskot MizuOne" className="h-44 w-auto mx-auto mt-3"/>
            {payMethod==='digital' ? (
              <>
                <h2 className="text-xl font-extrabold mt-1">Kartu berhasil dikreditkan ✓</h2>
                <p className="text-slate-500 text-sm mt-1 sub">Tap kartu ke mesin MizuOne kapan saja untuk melihat saldo terbaru.</p>
              </>
            ) : (
              <>
                <h2 className="text-xl font-extrabold mt-1">Tap kartu kamu sekarang</h2>
                <p className="text-slate-500 text-sm mt-1 sub">Tempelkan kartu MizuOne ke mesin dalam <b className="text-ink">5 menit</b> agar saldo masuk.</p>
                {secs > 0 ? (
                  <>
                    <div className="mt-4 inline-flex items-center gap-2 px-4 py-2 rounded-full bg-mizu-light text-mizu-700 font-bold">
                      <Ic.clock className="w-5 h-5"/> <span className="tabular-nums text-lg">{mm}:{ss2}</span>
                    </div>
                    <div className="mt-4 flex items-center justify-center gap-2 text-mizu">
                      <span className="w-2.5 h-2.5 rounded-full bg-mizu animate-ping"></span>
                      <span className="text-sm font-semibold">Menunggu tap kartu…</span>
                    </div>
                  </>
                ) : (
                  <p className="text-slate-400 text-sm mt-4">Waktu habis. Hubungi bantuan jika saldo belum masuk.</p>
                )}
              </>
            )}
            {secs===0 && payMethod!=='digital' ? (
              <Button variant="outline" size="lg" className="w-full mt-5" onClick={()=>go('kartu-home')}>Kembali ke Beranda</Button>
            ) : (
              <Button size="lg" className="w-full mt-5" onClick={()=>{ if(payMethod!=='digital') onTopup && onTopup(amount); go('kartu-sukses'); }} icon={<Ic.tap className="w-5 h-5"/>}>Sudah Tap</Button>
            )}
          </Card>
        )}
      </div>
      <QrisModal
        open={qr}
        amount={amount}
        qrContent={qrData.url}
        orderId={qrData.orderId}
        onClose={()=>setQr(false)}
        onPaid={()=>{ setQr(false); setSecs(5*60); setPayMethod('qris'); setPhase('tap'); }}
        checkStatus={window.AquAPI?.kartuTopupStatus}
      />
    </div>
  );
}

/* =========================================================================
   KARTU · SUKSES
   ========================================================================= */
function KartuSukses({ go, lastTopup, saldo, cardNo }){
  const bubbles = React.useMemo(()=>Array.from({length:16}).map((_,i)=>({ left:4+(i*6)%92, size:6+(i%4)*6, dur:6+(i%5)*1.6, delay:(i*0.4)%5 })),[]);
  return (
    <div className="relative min-h-screen wh-flow text-white overflow-hidden flex flex-col fade-in" data-screen-label="KartuSukses">
      <div className="wh-caustic" aria-hidden="true"></div>
      <div className="wh-bubbles" aria-hidden="true">{bubbles.map((b,i)=>(<span key={i} className="wh-bubble" style={{left:b.left+'%',width:b.size,height:b.size,animationDuration:b.dur+'s',animationDelay:b.delay+'s'}}></span>))}</div>
      <div className="relative z-10 flex-1 flex flex-col items-center justify-center px-6 text-center">
        <img src={imgSrc('mascot-mizuki-shoes.png')} alt="Maskot MizuOne menyapa" className="h-52 sm:h-60 w-auto drop-shadow-2xl pop"/>
        <h1 className="text-3xl font-extrabold tracking-tight mt-2">Topup Berhasil!</h1>
        <p className="text-white/90 mt-1"><b>{fmtRp(lastTopup)}</b> ditambahkan ke kartu ••{cardNo ? String(cardNo).slice(-4) : '????'}</p>
        <div className="mt-6 rounded-2xl bg-white/12 border border-white/25 backdrop-blur px-6 py-4">
          <div className="text-white/80 text-sm">Tap kartu ke mesin untuk aktifkan saldo</div>
          <div className="text-sm font-semibold mt-1 text-white/90">Saldo akan terupdate setelah tap</div>
        </div>
        <div className="flex gap-2.5 mt-7 w-full max-w-xs">
          <Button variant="white" className="flex-1" onClick={()=>go('kartu-home')}>Beranda Kartu</Button>
          <Button variant="glass" className="flex-1" onClick={()=>go('kartu-topup')}>Topup Lagi</Button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, { PhysicalCard, KartuLogin, KartuHome, KartuTopup, KartuSukses });
