from reportlab.lib.pagesizes import A4
from reportlab.lib.units import mm
from reportlab.lib import colors
from reportlab.platypus import SimpleDocTemplate, Table, TableStyle, Paragraph, Spacer
from reportlab.lib.styles import ParagraphStyle
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont

pdfmetrics.registerFont(TTFont('CN', '/usr/share/fonts/truetype/wqy/wqy-microhei.ttc', subfontIndex=0))
F = 'CN'

output = '/root/hb-opc/xiaokang/Bo_每日热量指南.pdf'
doc = SimpleDocTemplate(output, pagesize=A4, topMargin=25*mm, bottomMargin=20*mm, leftMargin=20*mm, rightMargin=20*mm)

title_s = ParagraphStyle('T', fontName=F, fontSize=22, leading=28, alignment=1, spaceAfter=6*mm, textColor=colors.HexColor('#1a1a2e'))
sub_s = ParagraphStyle('S', fontName=F, fontSize=11, leading=16, alignment=1, spaceAfter=10*mm, textColor=colors.HexColor('#666666'))
h2_s = ParagraphStyle('H', fontName=F, fontSize=14, leading=20, spaceBefore=8*mm, spaceAfter=4*mm, textColor=colors.HexColor('#16213e'))
body_s = ParagraphStyle('B', fontName=F, fontSize=10.5, leading=16, spaceAfter=2*mm, textColor=colors.HexColor('#333333'))
note_s = ParagraphStyle('N', fontName=F, fontSize=9.5, leading=14, spaceAfter=2*mm, textColor=colors.HexColor('#555555'), leftIndent=4*mm)
formula_s = ParagraphStyle('F', fontName=F, fontSize=10, leading=15, alignment=1, spaceAfter=4*mm, textColor=colors.HexColor('#2d4059'))
quick_s = ParagraphStyle('Q', fontName=F, fontSize=13, leading=20, alignment=1, spaceAfter=3*mm, textColor=colors.HexColor('#16213e'))

def make_table(data, widths, header_bg='#16213e'):
    t = Table(data, colWidths=widths)
    style = [
        ('FONT', (0,0), (-1,-1), F, 10),
        ('TEXTCOLOR', (0,0), (-1,-1), colors.HexColor('#333333')),
        ('BACKGROUND', (0,0), (-1,0), colors.HexColor(header_bg)),
        ('TEXTCOLOR', (0,0), (-1,0), colors.white),
        ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#cccccc')),
        ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
        ('ALIGN', (1,0), (-1,-1), 'CENTER'),
        ('TOPPADDING', (0,0), (-1,-1), 7),
        ('BOTTOMPADDING', (0,0), (-1,-1), 7),
        ('LEFTPADDING', (0,0), (-1,-1), 8),
    ]
    for i in range(1, len(data)):
        bg = '#f7f9fc' if i % 2 == 1 else '#eef2f7'
        style.append(('BACKGROUND', (0,i), (-1,i), colors.HexColor(bg)))
    t.setStyle(TableStyle(style))
    return t

els = []
els.append(Paragraph('Bo 每日热量指南', title_s))
els.append(Paragraph('基于个人体质与运动习惯的精准计算 · 2026年6月', sub_s))

# 基础数据
els.append(Paragraph('一、基础数据', h2_s))
bd = [
    ['项目', '数值', '项目', '数值'],
    ['身高', '183 cm', '体重', '82 kg（164斤）'],
    ['年龄', '38 岁', '目标', '80 kg（160斤）'],
    ['体型', '两年健身，肌肉量高于平均', '', ''],
]
t = Table(bd, colWidths=[70, 130, 70, 130])
st = [
    ('FONT', (0,0), (-1,-1), F, 10),
    ('TEXTCOLOR', (0,0), (-1,-1), colors.HexColor('#333333')),
    ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#16213e')),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('BACKGROUND', (0,0), (0,-1), colors.HexColor('#e8edf2')),
    ('BACKGROUND', (2,1), (2,-1), colors.HexColor('#e8edf2')),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#cccccc')),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('TOPPADDING', (0,0), (-1,-1), 6),
    ('BOTTOMPADDING', (0,0), (-1,-1), 6),
    ('LEFTPADDING', (0,0), (-1,-1), 8),
    ('SPAN', (1,3), (3,3)),
]
t.setStyle(TableStyle(st))
els.append(t)

# BMR
els.append(Paragraph('二、基础代谢率（BMR）', h2_s))
els.append(Paragraph('Mifflin-St Jeor 公式（男性）：', body_s))
els.append(Paragraph('BMR = 10 x 体重(kg) + 6.25 x 身高(cm) - 5 x 年龄 - 5', formula_s))
els.append(Paragraph('= 10x82 + 6.25x183 - 5x38 - 5 = 820 + 1144 - 190 - 5 = <b>1,769 大卡</b>', body_s))
els.append(Paragraph('考虑肌肉量偏高，实际 BMR 约 <b>1,800 ~ 1,850 大卡</b>', body_s))

# TDEE
els.append(Paragraph('三、每日总消耗（TDEE）', h2_s))
els.append(make_table([
    ['场景', '活动系数', '运动额外消耗', '每日总消耗'],
    ['不运动 / 正常工作', '1.3（久坐）', '0', '2,340~2,400'],
    ['40分钟游泳', '1.3+游泳', '400~500', '2,750~2,900'],
    ['50分钟撸铁+40分钟游泳', '1.3+撸铁+泳', '700~850', '3,050~3,250'],
], [120, 85, 95, 100]))

# 减脂目标
els.append(Paragraph('四、减脂热量目标（每日缺口 500 大卡）', h2_s))
els.append(Paragraph('目标：164斤 → 160斤（减2kg），每周减0.5kg', body_s))
els.append(Spacer(1, 3*mm))
els.append(make_table([
    ['场景', '每日总消耗', '减脂目标摄入'],
    ['不运动日', '~2,400 大卡', '1,900 大卡'],
    ['游泳日', '~2,800 大卡', '2,300 大卡'],
    ['撸铁+游泳日', '~3,100 大卡', '2,600 大卡'],
], [130, 120, 120], header_bg='#c0392b'))

# 实操
els.append(Paragraph('五、实操指南', h2_s))
els.append(Paragraph('<b>不运动日（1,900 大卡）</b>', body_s))
els.append(Paragraph('两顿正餐 800~900 大卡 + 小加餐 200 大卡（水果/坚果）', note_s))
els.append(Paragraph('<b>游泳日（2,300 大卡）</b>', body_s))
els.append(Paragraph('两餐 + 运动后加餐 400 大卡（蛋白质+碳水）', note_s))
els.append(Paragraph('<b>撸铁+游泳日（2,600 大卡）</b>', body_s))
els.append(Paragraph('三餐吃好，运动后必须补够', note_s))

# 铁律
els.append(Paragraph('六、铁律', h2_s))
rules = [
    ['', '规则'],
    ['!!!', '任何一天摄入不低于 1,500 大卡（否则失眠/暴食反扑）'],
    ['!!!', '运动后 1 小时内必吃（碳水+蛋白质 >= 400 大卡）'],
    ['!!!', '咖啡截止：下午 2 点前'],
    ['!!!', '当天没吃够就要睡 → 补一杯牛奶+坚果再睡'],
]
rt = Table(rules, colWidths=[30, 350])
rst = [
    ('FONT', (0,0), (-1,-1), F, 10.5),
    ('TEXTCOLOR', (0,0), (-1,-1), colors.HexColor('#333333')),
    ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#e74c3c')),
    ('TEXTCOLOR', (0,0), (-1,0), colors.white),
    ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#dddddd')),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
    ('TOPPADDING', (0,0), (-1,-1), 7),
    ('BOTTOMPADDING', (0,0), (-1,-1), 7),
    ('LEFTPADDING', (0,0), (-1,-1), 8),
    ('ALIGN', (0,0), (0,-1), 'CENTER'),
]
for i in range(1, len(rules)):
    bg = '#fff3e0' if i % 2 == 1 else '#fce8e8'
    rst.append(('BACKGROUND', (0,i), (-1,i), colors.HexColor(bg)))
rt.setStyle(TableStyle(rst))
els.append(rt)

# 速查
els.append(Paragraph('七、速查口诀', h2_s))
els.append(Spacer(1, 2*mm))
els.append(Paragraph('不动 1900  ·  游泳 2300  ·  撸铁+泳 2600  ·  底线 1500', quick_s))

doc.build(els)
print(f'Done: {output}')
