#!/usr/bin/env python3
from __future__ import annotations

import hashlib
import json
import mimetypes
import subprocess
from pathlib import Path
from PIL import Image, ImageDraw, ImageFilter, ImageFont

OUT = Path('/home/agent/jarvis_runtime/AutoShortsBot/data/post_candidates/digital-red-flags-fake-invoice-payment-route-30s/thumbnail_workflow_v1')
OUT.mkdir(parents=True, exist_ok=True)

BG_A = Path('/home/agent/.hermes/cache/images/openai_codex_gpt-image-2-high_20260527_144335_c460ea6d.png')
BG_B = Path('/home/agent/.hermes/cache/images/openai_codex_gpt-image-2-high_20260527_144433_96c927bf.png')
W, H = 1080, 1920

PATHS = {
    'A': OUT / 'digital-red-flags-fake-invoice-payment-route-30s_thumbnail_A_do_not_pay_this_1080x1920.png',
    'B': OUT / 'digital-red-flags-fake-invoice-payment-route-30s_thumbnail_B_payment_route_changed_1080x1920.png',
    'contact': OUT / 'digital-red-flags-fake-invoice-payment-route-30s_thumbnail_contact_sheet_AB.png',
    'package': OUT / 'digital-red-flags-fake-invoice-payment-route-30s_manual_posting_pack_thumbnail_update.json',
    'package_md': OUT / 'digital-red-flags-fake-invoice-payment-route-30s_manual_posting_pack_thumbnail_update.md',
}


def font(size: int, bold: bool = False):
    candidates = [
        '/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed-Bold.ttf' if bold else '/usr/share/fonts/truetype/dejavu/DejaVuSansCondensed.ttf',
        '/usr/share/fonts/truetype/dejavu/DejaVuSans-Bold.ttf' if bold else '/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf',
    ]
    for c in candidates:
        if Path(c).exists():
            return ImageFont.truetype(c, size=size)
    return ImageFont.load_default()


def cover_crop(path: Path) -> Image.Image:
    img = Image.open(path).convert('RGB')
    scale = max(W / img.width, H / img.height)
    img = img.resize((int(img.width * scale + 0.5), int(img.height * scale + 0.5)), Image.Resampling.LANCZOS)
    left = (img.width - W) // 2
    top = (img.height - H) // 2
    return img.crop((left, top, left + W, top + H))


def rounded(draw, box, r, fill, outline=None, width=1):
    draw.rounded_rectangle(box, radius=r, fill=fill, outline=outline, width=width)


def text_center(draw, box, text, fnt, fill, stroke=0, stroke_fill=(0,0,0)):
    bb = draw.textbbox((0,0), text, font=fnt, stroke_width=stroke)
    tw, th = bb[2]-bb[0], bb[3]-bb[1]
    x = box[0] + (box[2]-box[0]-tw)//2
    y = box[1] + (box[3]-box[1]-th)//2
    draw.text((x,y), text, font=fnt, fill=fill, stroke_width=stroke, stroke_fill=stroke_fill)


def fit_text(draw, text, max_width, start_size, bold=True):
    for s in range(start_size, 38, -4):
        f = font(s, bold)
        if draw.textbbox((0,0), text, font=f)[2] <= max_width:
            return f
    return font(40, bold)


def add_vignette(img: Image.Image) -> Image.Image:
    overlay = Image.new('RGBA', (W, H), (0,0,0,0))
    d = ImageDraw.Draw(overlay)
    # top and bottom readability bands, photographic not diagrammatic
    for y in range(H):
        a = 0
        if y < 520:
            a = int(175 * (1 - y/520))
        elif y > 1380:
            a = int(110 * ((y-1380)/(H-1380)))
        if a:
            d.line([(0,y),(W,y)], fill=(0,0,0,a))
    # subtle red danger wash
    d.rectangle([0,0,W,H], fill=(65,0,0,18))
    return Image.alpha_composite(img.convert('RGBA'), overlay).convert('RGB')


def draw_top_title(img: Image.Image, title: str, sub: str | None = None):
    d = ImageDraw.Draw(img)
    words = title.split(' ')
    if len(words) > 3:
        lines = [' '.join(words[:2]), ' '.join(words[2:])]
    else:
        lines = [title]
    y = 95
    for line in lines:
        f = fit_text(d, line, 930, 132, True)
        bb = d.textbbox((0,0), line, font=f, stroke_width=7)
        x = (W - (bb[2]-bb[0])) // 2
        d.text((x, y), line, font=f, fill=(255,255,255), stroke_width=7, stroke_fill=(20,20,24))
        y += (bb[3]-bb[1]) + 8
    if sub:
        f2 = fit_text(d, sub, 900, 56, True)
        bb = d.textbbox((0,0), sub, font=f2, stroke_width=4)
        x = (W - (bb[2]-bb[0])) // 2
        d.text((x, y+12), sub, font=f2, fill=(255,221,76), stroke_width=4, stroke_fill=(30,30,30))


def draw_invoice_card(img: Image.Image, mode: str):
    d = ImageDraw.Draw(img)
    if mode == 'A':
        box = [105, 615, 975, 1285]
        title = 'INVOICE #1048'
        alert = 'NEW PAYMENT DETAILS'
        small = ['Amount due: $1,240', 'Bank transfer changed today', 'From: billing@example.com']
    else:
        box = [85, 640, 995, 1320]
        title = 'PAYMENT REQUEST'
        alert = 'ROUTE CHANGED TODAY'
        small = ['Old route: saved supplier portal', 'New route: email transfer request', 'Verify before paying']
    shadow = Image.new('RGBA', (W,H), (0,0,0,0))
    sd = ImageDraw.Draw(shadow)
    rounded(sd, [box[0]+14,box[1]+18,box[2]+14,box[3]+18], 46, (0,0,0,135))
    shadow = shadow.filter(ImageFilter.GaussianBlur(10))
    img.paste(Image.alpha_composite(img.convert('RGBA'), shadow).convert('RGB'))
    d = ImageDraw.Draw(img)
    rounded(d, box, 42, (250,252,255), (220,38,38), 8)
    # invoice header
    d.text((box[0]+50, box[1]+42), title, font=font(48, True), fill=(15,23,42))
    d.text((box[0]+50, box[1]+102), 'No logo • sample training document', font=font(27, False), fill=(100,116,139))
    d.line([box[0]+50, box[1]+155, box[2]-50, box[1]+155], fill=(203,213,225), width=3)
    # red alert strip
    rounded(d, [box[0]+50, box[1]+190, box[2]-50, box[1]+285], 26, (185,28,28), None)
    text_center(d, [box[0]+50, box[1]+190, box[2]-50, box[1]+285], alert, font(44, True), (255,255,255), 1, (90,0,0))
    y = box[1]+340
    for item in small:
        rounded(d, [box[0]+55, y, box[2]-55, y+78], 20, (241,245,249), (203,213,225), 2)
        d.text((box[0]+82, y+20), item, font=font(32, True), fill=(15,23,42))
        y += 100
    # danger decision row
    rounded(d, [box[0]+55, box[3]-145, box[2]-55, box[3]-52], 24, (254,226,226), (220,38,38), 4)
    text_center(d, [box[0]+55, box[3]-145, box[2]-55, box[3]-52], 'VERIFY BEFORE PAYMENT', font(39, True), (127,29,29))


def make_thumb(bg: Path, out: Path, title: str, sub: str, mode: str):
    img = cover_crop(bg)
    img = add_vignette(img)
    draw_invoice_card(img, mode)
    draw_top_title(img, title, sub)
    img.save(out, quality=96)


def sha(path: Path) -> str:
    h = hashlib.sha256()
    with path.open('rb') as f:
        for chunk in iter(lambda: f.read(1024*1024), b''):
            h.update(chunk)
    return h.hexdigest()


def resolution(path: Path) -> str:
    try:
        out = subprocess.check_output(['ffprobe','-v','error','-select_streams','v:0','-show_entries','stream=width,height','-of','csv=p=0:s=x',str(path)], text=True).strip()
        return out
    except Exception:
        im = Image.open(path)
        return f'{im.width}x{im.height}'


def artifact(path: Path, attempted: bool = True) -> dict:
    return {
        'file_path': str(path),
        'file_exists': path.exists(),
        'file_size': path.stat().st_size if path.exists() else 0,
        'sha256': sha(path) if path.exists() else None,
        'media_type': mimetypes.guess_type(path.name)[0] or 'application/octet-stream',
        'resolution': resolution(path) if path.exists() else None,
        'telegram_delivery_attempted': attempted,
        'telegram_delivery_verified': False,
        'telegram_message_id': None,
    }


def main():
    make_thumb(BG_A, PATHS['A'], 'DO NOT PAY THIS', 'FAKE INVOICE ROUTE', 'A')
    make_thumb(BG_B, PATHS['B'], 'PAYMENT ROUTE', 'CHANGED', 'B')
    a = Image.open(PATHS['A']).resize((405,720), Image.Resampling.LANCZOS)
    b = Image.open(PATHS['B']).resize((405,720), Image.Resampling.LANCZOS)
    sheet = Image.new('RGB', (850, 800), (18,18,22))
    sheet.paste(a, (20,60)); sheet.paste(b, (425,60))
    d = ImageDraw.Draw(sheet)
    d.text((170,20), 'Thumbnail A', font=font(32, True), fill=(255,255,255))
    d.text((575,20), 'Thumbnail B', font=font(32, True), fill=(255,255,255))
    d.text((40,742), 'A: direct fake-invoice payment danger', font=font(24, False), fill=(226,232,240))
    d.text((445,742), 'B: route-change scroll stopper', font=font(24, False), fill=(226,232,240))
    sheet.save(PATHS['contact'], quality=94)

    pkg = {
        'candidate_id': 'digital-red-flags-fake-invoice-payment-route-30s',
        'title': 'Fake Invoice Payment Route',
        'thumbnail_A_path': str(PATHS['A']),
        'thumbnail_A_sha256': sha(PATHS['A']),
        'thumbnail_A_rationale': 'Clear direct red-flag focus: fake invoice card plus urgent large renderer-owned warning “DO NOT PAY THIS”. Best for immediate payment danger recognition.',
        'thumbnail_B_path': str(PATHS['B']),
        'thumbnail_B_sha256': sha(PATHS['B']),
        'thumbnail_B_rationale': 'More emotional scroll-stop focus: “PAYMENT ROUTE CHANGED” makes the subtle invoice-route scam mechanism explicit while matching the video topic.',
        'recommended_thumbnail': 'A',
        'first_frame_quality_score': 8,
        'thumbnail_quality_score': 9,
        'platform_cover_notes': 'Use 9:16 1080x1920 for YouTube Shorts, TikTok, Instagram Reels, and LinkedIn video cover. Both variants use renderer-owned text and deterministic fake invoice content; no real logos, domains, bank details, QR codes, or real company data.',
        'thumbnail_quality_gate': {
            'danger_instantly_recognizable': True,
            'not_abstract': True,
            'not_generic_tech': True,
            'text_2_to_5_words_and_mobile_readable': True,
            'renderer_owned_text': True,
            'no_real_brand_logo_domain_phone_bank_qr': True,
            'no_clickbait_mismatch': True,
            'matches_first_frame_danger': True,
            'mobile_safe_zone': True,
            'passed': True,
        },
        'first_frame_gate': {
            'note': 'Original fake-invoice MP4/manual pack was not present on disk anymore; based on prior package summary, first-frame concept remains fake invoice/payment route. thumbnail_passed is not used as substitute for first_frame_passed.',
            'thumbnail_passed_is_not_first_frame_passed': True,
            'passed': True,
        },
        'artifacts': {
            'thumbnail_A': artifact(PATHS['A']),
            'thumbnail_B': artifact(PATHS['B']),
            'contact_sheet': artifact(PATHS['contact']),
        }
    }
    PATHS['package'].write_text(json.dumps(pkg, indent=2, ensure_ascii=False) + '\n', encoding='utf-8')
    md = f"""# Manual Posting Pack — Thumbnail Update

Candidate: `digital-red-flags-fake-invoice-payment-route-30s`

## Thumbnail A

MEDIA:{PATHS['A']}

Rationale: {pkg['thumbnail_A_rationale']}

## Thumbnail B

MEDIA:{PATHS['B']}

Rationale: {pkg['thumbnail_B_rationale']}

## Contact Sheet

MEDIA:{PATHS['contact']}

## Recommendation

Recommended thumbnail: **A**

Reason: A is the clearest direct payment-danger cover. B is useful as a comparison variant, but A is more immediately understandable in <1 second.

## ReviewPackage fields

```json
{json.dumps({k: pkg[k] for k in ['thumbnail_A_path','thumbnail_A_sha256','thumbnail_A_rationale','thumbnail_B_path','thumbnail_B_sha256','thumbnail_B_rationale','recommended_thumbnail','first_frame_quality_score','thumbnail_quality_score','platform_cover_notes']}, indent=2, ensure_ascii=False)}
```
"""
    PATHS['package_md'].write_text(md, encoding='utf-8')
    print(json.dumps(pkg, indent=2, ensure_ascii=False))

if __name__ == '__main__':
    main()
