#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
生成买手店虚拟模特概念档案卡
"""
import os
import math
from PIL import Image, ImageDraw, ImageFont, ImageFilter

OUTPUT_DIR = "/Users/admin/boutique_project"

# 尝试加载字体
font_paths = [
    "/Library/Fonts/Arial Unicode.ttf",
    "/System/Library/Fonts/ヒラギノ角ゴシック W6.ttc",
    "/System/Library/Fonts/ヒラギノ角ゴシック W3.ttc",
]

def get_font(size, bold=False):
    for fp in font_paths:
        if os.path.exists(fp):
            try:
                return ImageFont.truetype(fp, size)
            except Exception:
                pass
    return ImageFont.load_default()

# 模特数据
MODELS = [
    {
        "code": "VERA-01",
        "name": "维拉",
        "style": "未来极简主义",
        "colors": [(10, 20, 40), (30, 60, 100), (80, 140, 200)],  # 深蓝冷调
        "accent": (120, 200, 255),
        "height": "178cm",
        "params": {"肩宽": "42", "腰": "60", "臀": "88"},
        "dna": ["不对称剪裁", "液态金属面料", "零缝线工艺"],
        "tech": "内置微流体温控系统，可随环境温度调节表面光泽",
        "desc": "以建筑线条为骨架，用 silence 代替喧嚣。VERA 是冷感未来美学的实体化。"
    },
    {
        "code": "LUMEN-02",
        "name": "流明",
        "style": "霓虹赛博朋克",
        "colors": [(30, 10, 40), (80, 20, 90), (180, 60, 160)],  # 紫粉霓虹
        "accent": (255, 80, 200),
        "height": "172cm",
        "params": {"肩宽": "40", "腰": "58", "臀": "86"},
        "dna": ["光纤编织", "夜光涂层", "全息投影配饰"],
        "tech": "服装纤维集成柔性LED，可通过APP切换1600万色发光模式",
        "desc": "夜幕即舞台。LUMEN 将城市霓虹穿在身上，每一帧都是动态视觉艺术。"
    },
    {
        "code": "NOVA-03",
        "name": "诺瓦",
        "style": "东方赛博",
        "colors": [(10, 35, 35), (20, 80, 80), (60, 160, 150)],  # 青绿+暗金
        "accent": (180, 220, 100),
        "height": "175cm",
        "params": {"肩宽": "41", "腰": "59", "臀": "87"},
        "dna": ["改良汉元素", "丝绸电路印花", "玉石温控扣"],
        "tech": "运用温感变色真丝，体温升高时浮现隐藏的水墨纹样",
        "desc": "青绿山水与电路板的对话。NOVA 证明传统与未来从不对立。"
    },
    {
        "code": "ECHO-04",
        "name": "回声",
        "style": "废土机能风",
        "colors": [(45, 38, 30), (90, 70, 55), (140, 100, 70)],  # 沙色锈红
        "accent": (210, 150, 90),
        "height": "180cm",
        "params": {"肩宽": "44", "腰": "62", "臀": "90"},
        "dna": ["模块化口袋系统", "再生尼龙", "磁吸快拆结构"],
        "tech": "面料搭载自修复涂层，轻微划痕在24小时内自动愈合",
        "desc": "为末世准备的高级定制。ECHO 的每一件衣服都是可穿戴的生存装备。"
    },
    {
        "code": "ARIA-05",
        "name": "咏叹调",
        "style": "生物科技感",
        "colors": [(35, 30, 45), (70, 60, 90), (140, 130, 180)],  # 珍珠白+淡紫
        "accent": (230, 210, 255),
        "height": "176cm",
        "params": {"肩宽": "39", "腰": "56", "臀": "85"},
        "dna": ["仿生褶皱", "珍珠光泽涂层", "有机曲线剪裁"],
        "tech": "面料植入生物发光蛋白，在暗光环境下发出柔和的生物荧光",
        "desc": "像水母一样呼吸。ARIA 模糊了有机生命与高级时装的边界。"
    },
]

def draw_gradient_bg(draw, width, height, colors):
    """绘制竖向渐变背景"""
    for y in range(height):
        ratio = y / height
        if ratio < 0.5:
            r = colors[0][0] + (colors[1][0] - colors[0][0]) * (ratio * 2)
            g = colors[0][1] + (colors[1][1] - colors[0][1]) * (ratio * 2)
            b = colors[0][2] + (colors[1][2] - colors[0][2]) * (ratio * 2)
        else:
            r = colors[1][0] + (colors[2][0] - colors[1][0]) * ((ratio - 0.5) * 2)
            g = colors[1][1] + (colors[2][1] - colors[1][1]) * ((ratio - 0.5) * 2)
            b = colors[1][2] + (colors[2][2] - colors[1][2]) * ((ratio - 0.5) * 2)
        draw.line([(0, y), (width, y)], fill=(int(r), int(g), int(b)))

def draw_grid(draw, width, height, color, spacing=60):
    """绘制科技感网格"""
    for x in range(0, width, spacing):
        draw.line([(x, 0), (x, height)], fill=color, width=1)
    for y in range(0, height, spacing):
        draw.line([(0, y), (width, y)], fill=color, width=1)

def draw_abstract_silhouette(draw, cx, cy, scale, color, accent, style_code):
    """绘制抽象人形轮廓，根据风格变化"""
    # 头部
    r_head = int(35 * scale)
    draw.ellipse([cx - r_head, cy - int(180*scale), cx + r_head, cy - int(110*scale)], outline=color, width=3)
    
    # 身体躯干 - 使用多边形营造科技感
    if style_code == "VERA-01":
        # 极简直线
        draw.line([(cx, cy - int(110*scale)), (cx, cy + int(50*scale))], fill=color, width=3)
        draw.line([(cx - int(40*scale), cy - int(60*scale)), (cx + int(40*scale), cy - int(60*scale))], fill=color, width=3)
        draw.line([(cx - int(40*scale), cy - int(60*scale)), (cx - int(50*scale), cy + int(120*scale))], fill=color, width=3)
        draw.line([(cx + int(40*scale), cy - int(60*scale)), (cx + int(50*scale), cy + int(120*scale))], fill=color, width=3)
        draw.line([(cx - int(50*scale), cy + int(120*scale)), (cx + int(50*scale), cy + int(120*scale))], fill=color, width=3)
    elif style_code == "LUMEN-02":
        # 霓虹发光感 - 更圆润
        pts = [
            (cx, cy - int(110*scale)),
            (cx - int(45*scale), cy - int(50*scale)),
            (cx - int(55*scale), cy + int(40*scale)),
            (cx - int(40*scale), cy + int(130*scale)),
            (cx + int(40*scale), cy + int(130*scale)),
            (cx + int(55*scale), cy + int(40*scale)),
            (cx + int(45*scale), cy - int(50*scale)),
        ]
        draw.polygon(pts, outline=color, width=3)
        draw.ellipse([cx - int(20*scale), cy - int(20*scale), cx + int(20*scale), cy + int(20*scale)], outline=accent, width=2)
    elif style_code == "NOVA-03":
        # 东方曲线
        pts = [
            (cx, cy - int(110*scale)),
            (cx - int(35*scale), cy - int(40*scale)),
            (cx - int(60*scale), cy + int(20*scale)),
            (cx - int(30*scale), cy + int(140*scale)),
            (cx + int(30*scale), cy + int(140*scale)),
            (cx + int(60*scale), cy + int(20*scale)),
            (cx + int(35*scale), cy - int(40*scale)),
        ]
        draw.polygon(pts, outline=color, width=3)
        # 斜跨腰带
        draw.line([(cx - int(50*scale), cy + int(10*scale)), (cx + int(50*scale), cy + int(60*scale))], fill=accent, width=3)
    elif style_code == "ECHO-04":
        # 机能块面
        draw.line([(cx, cy - int(110*scale)), (cx, cy + int(60*scale))], fill=color, width=3)
        draw.line([(cx - int(50*scale), cy - int(50*scale)), (cx + int(50*scale), cy - int(50*scale))], fill=color, width=3)
        draw.line([(cx - int(50*scale), cy - int(50*scale)), (cx - int(60*scale), cy + int(20*scale))], fill=color, width=3)
        draw.line([(cx + int(50*scale), cy - int(50*scale)), (cx + int(60*scale), cy + int(20*scale))], fill=color, width=3)
        draw.line([(cx - int(60*scale), cy + int(20*scale)), (cx - int(55*scale), cy + int(140*scale))], fill=color, width=3)
        draw.line([(cx + int(60*scale), cy + int(20*scale)), (cx + int(55*scale), cy + int(140*scale))], fill=color, width=3)
        # 模块口袋
        draw.rectangle([cx - int(30*scale), cy - int(20*scale), cx + int(30*scale), cy + int(30*scale)], outline=accent, width=2)
        draw.rectangle([cx - int(50*scale), cy + int(50*scale), cx - int(20*scale), cy + int(90*scale)], outline=accent, width=2)
        draw.rectangle([cx + int(20*scale), cy + int(50*scale), cx + int(50*scale), cy + int(90*scale)], outline=accent, width=2)
    else:
        # ARIA 有机曲线
        pts = [
            (cx, cy - int(110*scale)),
            (cx - int(30*scale), cy - int(50*scale)),
            (cx - int(50*scale), cy + int(10*scale)),
            (cx - int(35*scale), cy + int(80*scale)),
            (cx - int(45*scale), cy + int(150*scale)),
            (cx + int(45*scale), cy + int(150*scale)),
            (cx + int(35*scale), cy + int(80*scale)),
            (cx + int(50*scale), cy + int(10*scale)),
            (cx + int(30*scale), cy - int(50*scale)),
        ]
        draw.polygon(pts, outline=color, width=3)
        # 波浪装饰
        for i in range(3):
            y_base = cy + int((20 + i*30)*scale)
            draw.arc([cx - int(60*scale), y_base - int(10*scale), cx + int(60*scale), y_base + int(10*scale)], 0, 180, fill=accent, width=2)

    # 通用：数据点装饰
    for i in range(4):
        ang = math.pi * 2 * i / 4 + 0.3
        rx = cx + int(math.cos(ang) * r_head * 1.8)
        ry = cy - int(145*scale) + int(math.sin(ang) * r_head * 0.8)
        draw.ellipse([rx - 3, ry - 3, rx + 3, ry + 3], fill=accent)

def create_card(model, idx):
    W, H = 1080, 1920
    img = Image.new("RGB", (W, H), (20, 20, 20))
    draw = ImageDraw.Draw(img)
    
    # 背景渐变
    draw_gradient_bg(draw, W, H, model["colors"])
    
    # 半透明网格
    grid_color = tuple(min(255, c + 40) for c in model["colors"][0])
    draw_grid(draw, W, H, grid_color, spacing=80)
    
    # 边框装饰
    margin = 50
    draw.rectangle([margin, margin, W - margin, H - margin], outline=model["accent"], width=2)
    
    # 加载字体
    f_title = get_font(72, bold=True)
    f_code = get_font(36)
    f_name = get_font(48)
    f_body = get_font(28)
    f_small = get_font(24)
    f_tag = get_font(26)
    
    # 顶部：CODE
    draw.text((W//2, 100), model["code"], font=f_code, fill=(200, 200, 200), anchor="mm")
    draw.text((W//2, 180), model["name"], font=f_name, fill=model["accent"], anchor="mm")
    draw.text((W//2, 250), model["style"], font=f_body, fill=(180, 180, 180), anchor="mm")
    
    # 中央：抽象人形
    draw_abstract_silhouette(draw, W//2, H//2 - 50, 1.0, model["accent"], (255, 255, 255), model["code"])
    
    # 下方：数据参数
    y_start = H//2 + 280
    draw.text((W//2, y_start), f"身高 {model['height']}", font=f_body, fill=(220, 220, 220), anchor="mm")
    y_start += 60
    param_text = "  |  ".join([f"{k}: {v}" for k, v in model["params"].items()])
    draw.text((W//2, y_start), param_text, font=f_small, fill=(180, 180, 180), anchor="mm")
    
    # 穿搭DNA标签
    y_start += 80
    tag_w_total = sum([len(t) * 28 + 40 for t in model["dna"]]) + (len(model["dna"]) - 1) * 20
    x_start = (W - tag_w_total) // 2
    for tag in model["dna"]:
        tw = len(tag) * 28 + 40
        draw.rounded_rectangle([x_start, y_start, x_start + tw, y_start + 50], radius=8, outline=model["accent"], width=2)
        draw.text((x_start + tw//2, y_start + 25), tag, font=f_tag, fill=(240, 240, 240), anchor="mm")
        x_start += tw + 20
    
    # 科技特征
    y_start += 100
    draw.text((W//2, y_start), "▼ 科技内核 ▼", font=f_small, fill=model["accent"], anchor="mm")
    y_start += 50
    # 自动换行
    tech = model["tech"]
    max_chars = 26
    lines = [tech[i:i+max_chars] for i in range(0, len(tech), max_chars)]
    for line in lines:
        draw.text((W//2, y_start), line, font=f_small, fill=(200, 200, 200), anchor="mm")
        y_start += 40
    
    # 底部描述
    y_start += 30
    desc = model["desc"]
    max_chars = 24
    lines = [desc[i:i+max_chars] for i in range(0, len(desc), max_chars)]
    for line in lines:
        draw.text((W//2, y_start), line, font=f_small, fill=(160, 160, 160), anchor="mm")
        y_start += 40
    
    # 底部编号
    draw.text((W//2, H - 80), f"MODEL ARCHIVE // {idx+1:02d}/05", font=f_small, fill=(120, 120, 120), anchor="mm")
    
    # 添加轻微噪点/纹理感
    # （可选）简单高斯模糊边缘营造氛围
    
    return img

def main():
    os.makedirs(OUTPUT_DIR, exist_ok=True)
    paths = []
    for i, m in enumerate(MODELS):
        img = create_card(m, i)
        path = os.path.join(OUTPUT_DIR, f"model_{m['code'].lower()}.png")
        img.save(path, "PNG")
        paths.append(path)
        print(f"已生成: {path}")
    return paths

if __name__ == "__main__":
    main()
