import json, urllib.request, time, sys

API_KEY = "vio_sk_vA8llIYm51J3oyXtfevrM92yUBJ8-3IS1sIn6xydF8o"
BASE = "https://api.viostudio.id/v1"

urls = {}

def generate(slide_name, prompt):
    payload = {"prompt": prompt, "model": "gpt-image-2.0", "aspect_ratio": "3:4", "count": 1}
    print(f"\n🎨 {slide_name}...")
    sys.stdout.flush()
    for attempt in range(3):
        try:
            req = urllib.request.Request(f'{BASE}/images/generate',
                data=json.dumps(payload).encode(),
                headers={'Content-Type':'application/json','Authorization':f'Bearer {API_KEY}','User-Agent':'Mozilla/5.0'},
                method='POST')
            with urllib.request.urlopen(req, timeout=60) as resp:
                gen_id = json.loads(resp.read()).get('generation_ids',[0])[0]
                print(f"✅ Queued ID: {gen_id}")
                sys.stdout.flush()
                for i in range(30):
                    time.sleep(8)
                    try:
                        sr = urllib.request.Request(f'{BASE}/generations/{gen_id}',
                            headers={'Authorization':f'Bearer {API_KEY}','User-Agent':'Mozilla/5.0'})
                        with urllib.request.urlopen(sr, timeout=20) as s:
                            st = json.loads(s.read())
                            stat = st.get('status')
                            print(f"  ({i+1}/30) {stat}")
                            sys.stdout.flush()
                            if stat == 'completed':
                                print(f"✅ {slide_name} DONE!\n📸 {st.get('asset_url')}")
                                return st.get('asset_url')
                            elif stat == 'failed':
                                print(f"❌ FAILED: {st.get('error_message')}")
                                return None
                    except:
                        time.sleep(5)
        except Exception as e:
            print(f"  ⚠️ Retry {attempt+1}/3... ({e})")
            time.sleep(5)

urls['slide1'] = generate("Slide 1 - Cover", """Instagram carousel cover slide 3:4 aspect ratio ukuran feed Instagram. Flat vector illustration style.

Background gradasi dari soft cream (#FFF8F0) ke deep teal blue (#1A5F7A). Nuansa agak gelap misterius.

Ilustrasi: karakter berjalan di jalan melingkar seperti track lari yang bentuknya infinity loop. Di jalur yang sama dia melewati lubang yang sama berulang kali. Tiap putaran dia jatuh ke lubang yang sama. Di pinggir jalan ada tanda peringatan yang diabaikan. Di bawah tanah bayangan bawah sadar memegang cetak biru dari jalur yang sama dia yang mendesain loop ini.

Label di lubang: PASANGAN TOXIC BOSS GAK ADIL TEMEN MANIPULATIF KEBIASAAN BURUK.

Teks HOOK besar font bold di bagian atas:
REPETITION COMPULSION

Teks hook lanjutan ukuran sama:
KENAPA KAMU JATUH KE LUBANG YANG SAMA?

Teks sub-heading di bawah:
Kamu gak sial. Kamu cuma mengulang.

Desain bold striking dramatis font besar mudah terbaca.""")

urls['slide2'] = generate("Slide 2 - Apa Itu", """Instagram carousel slide 3:4 aspect ratio ukuran feed Instagram. Flat vector illustration style infografis.

Background gradasi soft cream ke deep teal blue. Aksen orange.

Ilustrasi: karakter kecil inner child berdiri di depan satu adegan yang belum selesai gambar samar orang tua yang membelakangi atau adegan penolakan. Di tangannya inner child memegang remote control dengan tombol REPLAY. Di layar TV besar di depannya adegan yang SAMA diputar ulang tapi kali ini dengan orang yang berbeda: pasangan, bos, teman. Semua versi remake dari adegan asli. Panah menghubungkan adegan asli ke semua remake: BAWAH SADAR MENCARI ENDING YANG BERBEDA.

Teks HEADLINE bold di atas:
APA ITU REPETITION COMPULSION?

Teks definisi:
Repetition compulsion adalah dorongan bawah sadar untuk MENGULANG situasi traumatis dari masa lalu berharap kali ini hasilnya BEDA.

Teks penjelasan:
Konsep dari Freud. Kamu gak sengaja milih pasangan yang mirip ayahmu. Bos yang mirip ibumu. Temen yang mirip bully SD-mu.

Teks bold orange:
Bukan kebetulan. Ini misi bawah sadar yang BELUM SELESAI.

Desain infografis edukatif agak dark.""")

urls['slide3'] = generate("Slide 3 - Mekanismenya", """Instagram carousel slide 3:4 aspect ratio ukuran feed Instagram. Flat vector illustration style infografis.

Background gradasi soft cream ke deep teal blue. Aksen orange.

Ilustrasi: sebuah file terbuka di otak folder besar dengan label UNFINISHED BUSINESS. Di dalam folder ada file-file lama: Ditolak Ayah UNRESOLVED, Dihina Guru UNRESOLVED, Diselingkuhi UNRESOLVED.

Dari folder ini keluar sinyal terus-menerus ke RADAR di depan otak. Radar ini memindai dunia dan mencari situasi yang MIRIP. Begitu ketemu: BEEP INI DIA KESEMPATAN UNTUK NYELESAIIN.

File yang sama punya sticky note: MISI Kali ini aku harus bikin dia BERUBAH. Kalo berhasil trauma lamanya SELESAI.

Tapi di bawah ada catatan kecil: Masalahnya orang sekarang bukan orang dulu. Dan ending-nya biasanya sama.

Teks HEADLINE bold di atas:
KENAPA OTAK NGULANG?

Teks step-by-step:
1. Ada trauma lama yang BELUM SELESAI luka yang gak pernah diakui atau diproses.
2. Bawah sadar nyimpen misi: Selesaikan ini.
3. Radar bawah sadar AKTIF mencari situasi yang MIRIP di kehidupan sekarang.
4. Begitu ketemu kamu tertarik tanpa sadar kenapa.
5. Kamu masuk ke situasi yang SAMA. Berharap KALI INI BERBEDA.

Teks penutup:
Tapi orang di depanmu bukan orang dulu. Dan ending-nya ya sama.

Desain infografis rapi serius.""")

urls['slide4'] = generate("Slide 4 - Contoh Pasangan", """Instagram carousel slide 3:4 aspect ratio ukuran feed Instagram. Flat vector illustration style komik vertikal.

Background gradasi soft cream ke deep teal blue.

Ilustrasi timeline vertikal:

Paling atas MASA KECIL: Seorang anak kecil berdiri di depan ayah atau ibu yang cuek sibuk sendiri gak merhatiin. Anak kecil pegang gambar yang dia bikin berharap dipuji. Tapi gak digubris. Ekspresi sedih. Label TRAUMA ASLI Aku gak cukup berharga untuk diperhatiin.

Tengah PACARAN PERTAMA: Pasangan yang satu cuek main HP yang satu dewasa nungguin perhatian ekspresi sama kayak waktu kecil. Label REMAKE 1.

Tengah PACARAN KEDUA: Adegan mirip beda orang beda tempat tapi dinamika sama. REMAKE 2.

Paling bawah SEKARANG: Pasangan lagi adegan sama. Tapi kali ini karakter yang udah lebih tua sadar ada kilasan ke masa kecil. Ekspresi mulai tercerahkan. Label REMAKE 3.

Teks di samping timeline:
Bukan tipe pasangan yang kamu pilih. Tapi POLA yang kamu ulang.

Teks penutup bawah:
Kamu gak cari pasangan. Kamu cari seseorang yang bisa kamu selesaiin misi masa kecilmu bikin dia akhirnya NGELIAT kamu.

Desain komik timeline relatable ngena.""")

print("\n✅ BATCH 1-4 COMPLETE!")
print("\nURLs:", json.dumps(urls, indent=2))
