"""
VoxelRealm License Generator — Prestigious Certificate Edition
"""
import os, json, datetime, hashlib, base64, textwrap, math
from pathlib import Path
from fpdf import FPDF, XPos, YPos
from cryptography.hazmat.primitives.asymmetric import padding
from cryptography.hazmat.primitives import hashes, serialization

KEYS_DIR  = Path(__file__).parent / "keys"
COUNTER_F = Path(__file__).parent / "license_counter.json"

_FONT_DIR  = Path(__file__).parent
FONT_REG       = str(_FONT_DIR / "FreeSans.otf")
FONT_BOLD      = str(_FONT_DIR / "FreeSansBold.otf")
FONT_MONO      = str(_FONT_DIR / "AdwaitaMono-Regular.ttf")
FONT_MONO_BOLD = str(_FONT_DIR / "AdwaitaMono-Bold.ttf")

W, H = 210, 297

# ── Color palette ─────────────────────────────────────────────────────────────
GOLD     = (212, 175,  55)
GOLD2    = (244, 185,  66)
GOLD_DIM = (140, 105,  20)
AMBER    = (200, 120,  30)
DARK_BG  = (  8,   8,  20)
MID_BG   = ( 14,  12,  28)
BOX_BG   = ( 18,  16,  40)
DARK_BOX = ( 10,   8,  20)
WHITE    = (255, 255, 255)
SILVER   = (180, 185, 210)
DIM      = ( 90,  90, 130)
GREEN    = ( 50, 200,  70)
DARK_GR  = (  0, 100,   0)
BLUE_ACC = (100, 150, 220)
RED_ACC  = (180,  50,  50)


def _load_counter():
    if COUNTER_F.exists():
        return json.loads(COUNTER_F.read_text())["count"]
    return 0

def _save_counter(n):
    COUNTER_F.write_text(json.dumps({"count": n}))

def _sign(data: str) -> str:
    priv = serialization.load_pem_private_key(
        (KEYS_DIR / "private.pem").read_bytes(), password=None
    )
    sig = priv.sign(data.encode(), padding.PKCS1v15(), hashes.SHA512())
    return base64.b64encode(sig).decode()

def _pubkey_fingerprint() -> str:
    pub = (KEYS_DIR / "public.pem").read_bytes()
    h = hashlib.sha256(pub).hexdigest()
    return ':'.join(h[i:i+4] for i in range(0, 32, 4)).upper()


# ── Drawing helpers ───────────────────────────────────────────────────────────

def _fill(pdf, color):
    pdf.set_fill_color(*color)

def _text(pdf, color):
    pdf.set_text_color(*color)

def _draw_border(pdf):
    """Three-layer ornate border with corner diamonds."""
    # Outer thick gold frame
    _fill(pdf, GOLD2)
    pdf.rect(5, 5, W-10, 2.0, 'F')           # top
    pdf.rect(5, H-7, W-10, 2.0, 'F')          # bottom
    pdf.rect(5, 5, 2.0, H-10, 'F')            # left
    pdf.rect(W-7, 5, 2.0, H-10, 'F')          # right

    # Middle amber frame
    _fill(pdf, AMBER)
    pdf.rect(8.5, 8.5, W-17, 0.8, 'F')
    pdf.rect(8.5, H-9.3, W-17, 0.8, 'F')
    pdf.rect(8.5, 8.5, 0.8, H-17, 'F')
    pdf.rect(W-9.3, 8.5, 0.8, H-17, 'F')

    # Inner thin gold frame
    _fill(pdf, GOLD_DIM)
    pdf.rect(11, 11, W-22, 0.4, 'F')
    pdf.rect(11, H-11.4, W-22, 0.4, 'F')
    pdf.rect(11, 11, 0.4, H-22, 'F')
    pdf.rect(W-11.4, 11, 0.4, H-22, 'F')

    # Corner ornaments using ♦ character
    _text(pdf, GOLD2)
    pdf.set_font("Sans", "B", 14)
    for cx, cy in [(3, 3), (W-11, 3), (3, H-12), (W-11, H-12)]:
        pdf.set_xy(cx, cy)
        pdf.cell(8, 9, "♦", align='C')


def _sep(pdf, y, w_pct=0.72):
    """Decorative separator with center diamond."""
    cx   = W / 2
    half = W * w_pct / 2
    _fill(pdf, GOLD)
    pdf.rect(cx - half, y + 1.0, half - 6, 0.4, 'F')
    pdf.rect(cx + 6,    y + 1.0, half - 6, 0.4, 'F')
    _text(pdf, GOLD2)
    pdf.set_font("Sans", "B", 9)
    pdf.set_xy(cx - 5, y - 1.5)
    pdf.cell(10, 6, "♦", align='C')


def _field(pdf, label_uk, label_en, value, y, accent, mono=False):
    """Elegant field box with bilingual label."""
    bh = 15
    # Outer shadow
    _fill(pdf, (5, 5, 12))
    pdf.rect(20, y+1, W-40, bh, 'F')
    # Box
    _fill(pdf, BOX_BG)
    pdf.rect(19, y, W-38, bh, 'F')
    # Top accent line
    _fill(pdf, accent)
    pdf.rect(19, y, W-38, 0.6, 'F')
    # Left accent bar (thick + thin)
    _fill(pdf, accent)
    pdf.rect(19, y, 3.5, bh, 'F')
    _fill(pdf, tuple(max(0, c-80) for c in accent))
    pdf.rect(22.5, y, 1.0, bh, 'F')
    # Label
    pdf.set_font("Sans", "B", 6)
    _text(pdf, tuple(max(0, c-50) for c in accent))
    pdf.set_xy(26, y + 2.2)
    pdf.cell(80, 3.5, f"{label_uk.upper()}  /  {label_en.upper()}")
    # Value
    if mono:
        pdf.set_font("Mono", "B", 11)
    else:
        pdf.set_font("Sans", "B", 13)
    _text(pdf, WHITE)
    pdf.set_xy(26, y + 7.5)
    pdf.cell(W - 65, 7, str(value))
    # Right ornament
    _fill(pdf, accent)
    pdf.ellipse(W - 32, y + bh/2 - 2, 4, 4, 'F')
    _fill(pdf, DARK_BG)
    pdf.ellipse(W - 31, y + bh/2 - 1, 2, 2, 'F')


def _grand_seal(pdf, cx, cy):
    """Multi-ring official seal with circumference dots."""
    r = 19

    # Outer glow (faint rings)
    for ri, col in [(r+5, (18, 15, 5)), (r+3, (28, 24, 8)), (r+1.5, (40, 33, 10))]:
        _fill(pdf, col)
        pdf.ellipse(cx-ri, cy-ri, ri*2, ri*2, 'F')

    # Main seal fill
    _fill(pdf, (14, 10, 4))
    pdf.ellipse(cx-r, cy-r, r*2, r*2, 'F')

    # Concentric gold rings
    pdf.set_draw_color(*GOLD2)
    pdf.set_line_width(1.8)
    pdf.ellipse(cx-r, cy-r, r*2, r*2, 'D')
    pdf.set_line_width(0.5)
    pdf.ellipse(cx-r+3.5, cy-r+3.5, (r-3.5)*2, (r-3.5)*2, 'D')
    pdf.set_draw_color(*AMBER)
    pdf.set_line_width(0.3)
    pdf.ellipse(cx-r+5.5, cy-r+5.5, (r-5.5)*2, (r-5.5)*2, 'D')

    # 16 dots around circumference
    _fill(pdf, GOLD2)
    for i in range(16):
        angle = i * (2 * math.pi / 16) - math.pi/2
        dx = math.cos(angle) * (r + 2.5)
        dy = math.sin(angle) * (r + 2.5)
        s  = 1.4 if i % 4 == 0 else 0.9
        pdf.ellipse(cx+dx-s/2, cy+dy-s/2, s, s, 'F')

    # Seal text
    _text(pdf, GOLD2)
    pdf.set_font("Sans", "B", 6.5)
    pdf.set_xy(cx-r, cy-9)
    pdf.cell(r*2, 5, "♦  VOXELREALM  ♦", align='C')

    pdf.set_font("Sans", "", 5)
    _text(pdf, SILVER)
    pdf.set_xy(cx-r, cy-4.5)
    pdf.cell(r*2, 4, "OFFICIALLY", align='C')

    _text(pdf, GOLD)
    pdf.set_font("Sans", "B", 9)
    pdf.set_xy(cx-r, cy+0)
    pdf.cell(r*2, 5, "VERIFIED", align='C')

    pdf.set_font("Mono", "", 4.5)
    _text(pdf, (160, 140, 80))
    pdf.set_xy(cx-r, cy+5.5)
    pdf.cell(r*2, 4, "AUTHENTIC LICENSE", align='C')


# ── Main generator ────────────────────────────────────────────────────────────

def generate_license_pdf(nickname: str, out_path: str) -> dict:
    """Generate a signed prestigious PDF license. Returns metadata dict."""
    count  = _load_counter() + 1
    _save_counter(count)

    now      = datetime.datetime.now(datetime.UTC)
    date_s   = now.strftime("%Y-%m-%d %H:%M:%S UTC")
    lic_id   = f"VR-{count:06d}"
    fp       = _pubkey_fingerprint()
    payload  = f"LICENSE:{lic_id}|NICKNAME:{nickname}|DATE:{date_s}"
    p_hash   = hashlib.sha256(payload.encode()).hexdigest().upper()
    sig      = _sign(payload)

    pdf = FPDF(orientation='P', unit='mm', format='A4')
    pdf.add_font("Sans",  "",  FONT_REG)
    pdf.add_font("Sans",  "B", FONT_BOLD)
    pdf.add_font("Mono",  "",  FONT_MONO)
    pdf.add_font("Mono",  "B", FONT_MONO_BOLD)
    pdf.add_page()
    pdf.set_auto_page_break(False)

    # ── Full page background ───────────────────────────────────────────────────
    _fill(pdf, DARK_BG)
    pdf.rect(0, 0, W, H, 'F')

    # Slightly lighter header region
    _fill(pdf, MID_BG)
    pdf.rect(0, 0, W, 66, 'F')

    # ── Top decorative strips ──────────────────────────────────────────────────
    _fill(pdf, GOLD2)
    pdf.rect(0, 0, W, 3.0, 'F')
    _fill(pdf, AMBER)
    pdf.rect(0, 3.0, W, 1.2, 'F')
    _fill(pdf, GOLD_DIM)
    pdf.rect(0, 4.2, W, 0.5, 'F')

    # Bottom decorative strips
    _fill(pdf, GOLD2)
    pdf.rect(0, H-3.0, W, 3.0, 'F')
    _fill(pdf, AMBER)
    pdf.rect(0, H-4.2, W, 1.2, 'F')

    # ── Border ────────────────────────────────────────────────────────────────
    _draw_border(pdf)

    # ── Stars row ─────────────────────────────────────────────────────────────
    _text(pdf, GOLD)
    pdf.set_font("Sans", "B", 8)
    pdf.set_xy(0, 11)
    pdf.cell(W, 5, "♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦   ♦", align='C')

    # ── Main title (shadow + main) ─────────────────────────────────────────────
    # Shadow
    _text(pdf, (50, 38, 5))
    pdf.set_font("Sans", "B", 52)
    pdf.set_xy(1.5, 19.5)
    pdf.cell(W, 18, "VoxelRealm", align='C')
    # Main
    _text(pdf, GOLD2)
    pdf.set_xy(0, 18)
    pdf.cell(W, 18, "VoxelRealm", align='C')

    # ── Subtitle (spaced caps) ─────────────────────────────────────────────────
    _text(pdf, SILVER)
    pdf.set_font("Sans", "", 8.5)
    pdf.set_xy(0, 37)
    pdf.cell(W, 5, "O P E N   V O X E L   W O R L D   ·   V U L K A N   ·   C + + 2 0   ·   F R E E", align='C')

    # ── Decorative dots row ───────────────────────────────────────────────────
    _text(pdf, AMBER)
    pdf.set_font("Sans", "B", 7)
    pdf.set_xy(0, 43)
    pdf.cell(W, 5, "·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·  ·", align='C')

    # ── Certificate title band ────────────────────────────────────────────────
    _fill(pdf, (22, 18, 48))
    pdf.rect(19, 50, W-38, 15, 'F')
    _fill(pdf, GOLD2)
    pdf.rect(19, 50, W-38, 1.2, 'F')
    pdf.rect(19, 63.8, W-38, 1.2, 'F')
    _fill(pdf, AMBER)
    pdf.rect(19, 51.2, W-38, 0.5, 'F')
    pdf.rect(19, 63.3, W-38, 0.5, 'F')

    _text(pdf, GOLD2)
    pdf.set_font("Sans", "B", 11.5)
    pdf.set_xy(19, 53.5)
    pdf.cell(W-38, 9, "ОФІЦІЙНИЙ СЕРТИФІКАТ  ♦  OFFICIAL LICENSE CERTIFICATE", align='C')

    # ── Separator ─────────────────────────────────────────────────────────────
    _sep(pdf, 67, 0.75)

    # ── Four field boxes ───────────────────────────────────────────────────────
    _field(pdf, "Номер ліцензії", "License Number",  lic_id,          70,  GOLD2,       mono=True)
    _field(pdf, "Нікнейм гравця", "Player Nickname", nickname,        87,  (232,108,42))
    _field(pdf, "Дата видачі",    "Issue Date",      date_s,         104,  (70,180,100), mono=True)
    _field(pdf, "Копія №",        "Copy Number",     f"#{count:,}",  121,  BLUE_ACC)

    # ── Separator ─────────────────────────────────────────────────────────────
    _sep(pdf, 139, 0.72)

    # ── SHA-256 payload hash ───────────────────────────────────────────────────
    _fill(pdf, DARK_BOX)
    pdf.rect(19, 143, W-38, 11, 'F')
    _fill(pdf, (25, 40, 25))
    pdf.rect(19, 143, 2.5, 11, 'F')

    _text(pdf, DIM)
    pdf.set_font("Sans", "B", 5.5)
    pdf.set_xy(24, 144.5)
    pdf.cell(55, 3.5, "SHA-256 PAYLOAD HASH")

    _text(pdf, (140, 200, 140))
    pdf.set_font("Mono", "", 6)
    pdf.set_xy(24, 148.5)
    pdf.cell(W-48, 4, p_hash)

    # ── RSA Signature block ───────────────────────────────────────────────────
    _text(pdf, GOLD)
    pdf.set_font("Sans", "B", 7.5)
    pdf.set_xy(19, 157)
    pdf.cell(W-38, 5, "RSA-8192 DIGITAL SIGNATURE  —  SHA-512 / PKCS#1 v1.5  —  CLICK TO VERIFY",
             new_x=XPos.LMARGIN, new_y=YPos.NEXT)

    sig_lines = textwrap.wrap(sig, 108)
    box_h = len(sig_lines) * 3.6 + 5

    _fill(pdf, (5, 7, 10))
    pdf.rect(19, 163, W-38, box_h, 'F')
    _fill(pdf, DARK_GR)
    pdf.rect(19, 163, 2.5, box_h, 'F')
    _fill(pdf, (0, 60, 0))
    pdf.rect(21.5, 163, 0.8, box_h, 'F')
    _fill(pdf, GREEN)
    pdf.rect(19, 163, W-38, 0.5, 'F')

    _text(pdf, GREEN)
    pdf.set_font("Mono", "", 5.0)
    yy = 165.5
    for line in sig_lines:
        pdf.set_xy(24, yy)
        pdf.cell(W-46, 3.6, line)
        yy += 3.6

    # ── Public key fingerprint ────────────────────────────────────────────────
    y_fp = yy + 3
    _fill(pdf, (12, 12, 28))
    pdf.rect(19, y_fp, W-38, 9, 'F')
    _fill(pdf, (30, 30, 80))
    pdf.rect(19, y_fp, 2.5, 9, 'F')

    _text(pdf, DIM)
    pdf.set_font("Sans", "B", 6)
    pdf.set_xy(24, y_fp + 1.8)
    pdf.cell(42, 3.5, "PUBLIC KEY  SHA-256 :")

    _text(pdf, (150, 165, 215))
    pdf.set_font("Mono", "B", 6)
    pdf.set_xy(65, y_fp + 1.8)
    pdf.cell(W-84, 3.5, fp)

    _text(pdf, (60, 60, 100))
    pdf.set_font("Sans", "", 5.5)
    pdf.set_xy(24, y_fp + 5.5)
    pdf.cell(W-48, 3, "Public key available at: server /api/public-key  ·  Verify with: openssl dgst -sha512 -verify public.pem -signature <sig.bin> payload.txt")

    # ── Separator ─────────────────────────────────────────────────────────────
    y_sep2 = y_fp + 13
    _sep(pdf, y_sep2, 0.70)

    # ── Terms of use ──────────────────────────────────────────────────────────
    y_terms = y_sep2 + 7
    _fill(pdf, (13, 11, 26))
    pdf.rect(19, y_terms, W-38, 36, 'F')
    _fill(pdf, GOLD2)
    pdf.rect(19, y_terms, W-38, 1.0, 'F')
    _fill(pdf, AMBER)
    pdf.rect(19, y_terms+1.0, W-38, 0.4, 'F')

    _text(pdf, GOLD)
    pdf.set_font("Sans", "B", 7)
    pdf.set_xy(23, y_terms + 3.5)
    pdf.cell(W-46, 4.5, "УМОВИ ВИКОРИСТАННЯ  ♦  TERMS OF USE",
             new_x=XPos.LMARGIN, new_y=YPos.NEXT)

    _text(pdf, SILVER)
    pdf.set_font("Sans", "", 6.5)
    terms = [
        "Ця ліцензія надає власнику невиключне, непередаване право на особисте використання VoxelRealm.",
        "This license grants the holder a non-exclusive, non-transferable right to personally use VoxelRealm.",
        "Заборонено: перепродаж, поширення, декомпіляція без письмового дозволу автора.",
        "Prohibited: resale, redistribution, or decompilation without the author's written permission.",
        "Автентичність підтверджується підписом RSA-8192 вище. Публічний ключ доступний на запит.",
        "Authenticity verified by RSA-8192 signature above. Public key available on request.",
    ]
    _text(pdf, (120, 125, 160))
    for t in terms:
        pdf.set_x(23)
        pdf.cell(W-95, 4.3, t, new_x=XPos.LMARGIN, new_y=YPos.NEXT)

    # ── Grand seal (bottom right of terms area) ────────────────────────────────
    seal_cx = W - 35
    seal_cy = y_terms + 18
    _grand_seal(pdf, seal_cx, seal_cy)

    # Seal license ID inside
    _text(pdf, (180, 160, 90))
    pdf.set_font("Mono", "", 4.5)
    pdf.set_xy(seal_cx - 19, seal_cy + 10)
    pdf.cell(38, 4, lic_id, align='C')

    # ── Signature line area (below terms) ─────────────────────────────────────
    y_sig = y_terms + 40
    # Three signature/stamp lines
    _fill(pdf, GOLD_DIM)
    pdf.rect(19, y_sig, 50, 0.3, 'F')
    pdf.rect(80, y_sig, 50, 0.3, 'F')

    _text(pdf, DIM)
    pdf.set_font("Sans", "", 5.5)
    pdf.set_xy(19, y_sig + 1.5)
    pdf.cell(50, 3.5, "Підпис / Signature", align='C')
    pdf.set_xy(80, y_sig + 1.5)
    pdf.cell(50, 3.5, "Дата / Date", align='C')

    # ── Footer ────────────────────────────────────────────────────────────────
    _fill(pdf, (14, 12, 28))
    pdf.rect(19, H-16, W-38, 7, 'F')

    _text(pdf, (70, 70, 100))
    pdf.set_font("Sans", "", 5.5)
    pdf.set_xy(22, H-14.5)
    pdf.cell((W-38)*0.5, 4,
        f"VoxelRealm  ·  {lic_id}  ·  RSA-8192 Signed")
    pdf.set_xy(22 + (W-38)*0.5, H-14.5)
    pdf.cell((W-38)*0.5, 4, date_s, align='R')

    _text(pdf, (50, 50, 80))
    pdf.set_font("Sans", "", 5)
    pdf.set_xy(22, H-11)
    pdf.cell(W-44, 3.5,
        "This document is cryptographically signed and its authenticity can be verified using the RSA-8192 public key.",
        align='C')

    pdf.output(out_path)

    return {
        "license_id":   lic_id,
        "copy_number":  count,
        "nickname":     nickname,
        "date":         date_s,
        "payload_hash": p_hash,
        "signature":    sig,
        "fingerprint":  fp,
    }


if __name__ == "__main__":
    meta = generate_license_pdf("DragonSlayer99", "/tmp/test_license.pdf")
    print(f"Generated: {meta['license_id']}  Copy #{meta['copy_number']}")
    print("PDF: /tmp/test_license.pdf")
