#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""生成 5 张商务概念插画（MiniMax image-01）。
调用于「生成阶段」，不得写入成品页。
色板：宝锐蓝 #1F4E9C 主 + IKB #002FA7 点缀；无文字、无真人肖像。
"""
import json
import os
import re
import sys
import time
import urllib.request

ENV = os.path.expanduser('~/.hermes/.env')
KEY = None
BASE = 'https://api.minimaxi.com/v1/image_generation'
try:
    txt = open(ENV, encoding='utf-8').read()
    m = re.search(r'^MINIMAX_CN_API_KEY=(.*)$', txt, re.M)
    if m:
        KEY = m.group(1).strip()
except Exception:
    pass
if not KEY:
    KEY = open(os.path.expanduser('~/.config/minimax/music_api_key')).read().strip()

BASE_DIR = '/Users/liuxinyuan/Desktop/Hermes输出-工作类/培训与上手/培训/_img_price_deck'
os.makedirs(BASE_DIR, exist_ok=True)

NOTEXT = ('no text, no words, no letters, no numbers, no typography, no watermark, '
          'no signature, no logo, no captions')
NOPEOPLE = ('absolutely no faces, no realistic human beings, no photorealism, '
            'no realistic anatomy, faceless, shapes only')
PAL = ('Strict limited color palette: deep corporate blue #1F4E9C as the dominant color, '
       'electric ultramarine #002FA7 used only as small accents, off-white #FAFAF8 '
       'background, thin crisp linework')

PROMPTS = [
    ('scene_tug',
     'Flat vector business concept illustration, Swiss international minimalist graphic '
     'poster. A negotiation scene: a long horizontal table in the middle; on the left and '
     'right, two opposing sides rendered as abstract faceless geometric blocks and simple '
     'rectangles only (' + NOPEOPLE + '), pulling a taut rope in a tug of war across the '
     'table; bold tension lines, small motion marks, converging pressure lines toward the '
     'rope. ' + PAL + ', flat 2D, generous negative space, editorial poster composition.'),

    ('scene_weigh',
     'Flat vector business concept illustration, Swiss international minimalist graphic '
     'poster. One single anonymous faceless geometric figure made of plain shapes '
     '(' + NOPEOPLE + ') standing at the center, hesitating between two options: on the '
     'left a pathway with one stack of geometric blocks, on the right a different pathway '
     'with a different stack; above them a simple balance-scale motif tipping slightly '
     'to one side; a dashed branching arrow splitting left and right. ' + PAL + ', flat '
     '2D, thin clean lines, generous negative space, editorial poster composition.'),

    ('scene_deal',
     'Flat vector business concept illustration, Swiss international minimalist graphic '
     'poster. Two extremely simplified flat geometric hands, bold minimal icon-like '
     'silhouettes with simple five fingers, meeting in a handshake at the center of the '
     'frame, perfectly symmetrical and anatomically simple (' + NOPEOPLE + '); clean '
     'converging lines pointing to the handshake, a small upward geometric arrow, and a '
     'minimal checkmark drawn with two clean strokes. ' + PAL + ', flat 2D vector, thin '
     'clean lines, generous negative space, editorial poster composition.'),

    ('scene_price',
     'Flat vector business concept illustration, Swiss international minimalist graphic '
     'poster. An abstract "too expensive" concept: one oversized completely BLANK paper '
     'price tag shape with a diagonal rejection slash, beside neat stacks of geometric '
     'coin discs; a simple seesaw / balance beam tipping between a coin and a product '
     'cube, plus a bold downward arrow. The tag is empty with no markings. ' + PAL +
     ', flat 2D vector, thin clean lines, generous negative space, editorial poster '
     'composition.'),

    ('jobs_cart',
     'Flat vector business concept illustration, Swiss international minimalist graphic '
     'poster. A conceptual metaphor of progress and innovation: on the left a simple '
     'flat geometric wheeled carriage silhouette made of circles and rectangles '
     '(no animal, ' + NOPEOPLE + '), in the middle a bold horizontal arrow, on the '
     'right a sleek simple flat geometric car silhouette; expressing the shift from '
     'a faster horse to the automobile. ' + PAL + ', flat 2D vector, thin clean lines, '
     'generous negative space, editorial poster composition.'),
]


def gen(name, prompt):
    png = os.path.join(BASE_DIR, name + '.png')
    if os.path.exists(png) and os.path.getsize(png) > 20000:
        print('  %-12s 已存在，跳过 (%dKB)' % (name, os.path.getsize(png) // 1024))
        return True
    full = prompt + ' ' + NOTEXT + '.'
    for attempt in range(3):
        try:
            payload = json.dumps({'model': 'image-01', 'prompt': full,
                                  'image_size': '1536x1024', 'num_images': 1}).encode()
            req = urllib.request.Request(BASE, data=payload,
                                         headers={'Authorization': 'Bearer ' + KEY,
                                                  'Content-Type': 'application/json'},
                                         method='POST')
            with urllib.request.urlopen(req, timeout=120) as resp:
                d = json.loads(resp.read())
            if d.get('base_resp', {}).get('status_code') not in (0, None):
                print('  %-12s 接口错误 %s' % (name, d.get('base_resp')))
            url = (d.get('data') or {}).get('image_urls', [''])[0] if isinstance(
                d.get('data'), dict) else (d.get('data') or [''])[0]
            if not url:
                print('  %-12s 第%d次 空URL，重试' % (name, attempt + 1))
                time.sleep(3)
                continue
            urllib.request.urlretrieve(url, png)
            print('  %-12s OK %dKB' % (name, os.path.getsize(png) // 1024))
            return True
        except Exception as e:
            print('  %-12s 第%d次失败 %s' % (name, attempt + 1, e))
            time.sleep(4)
    print('  %-12s 彻底失败' % name)
    return False


if __name__ == '__main__':
    print('MiniMax image_generation ->', BASE_DIR)
    okn = 0
    for n, p in PROMPTS:
        if gen(n, p):
            okn += 1
        time.sleep(1)
    print('完成 %d/%d' % (okn, len(PROMPTS)))
