"""
GLAMWalk -- Volume 5: From Data to Product
06_kdp_print_cover_math.py

Real KDP paperback and hardcover wraparound cover math, including the calibration-distance warning that flags when a requested trim size is far from any confirmed data point.

Source: Volume Five, Sections 4.1-4.3
Targets Python 3.11.4 -- see Volume One, Chapter 1.5/1.6.
"""

# KDP's own documented per-page spine thickness, by interior paper type —
# these are NOT the same for every book, and using the wrong one produces
# a cover that's wrong by a small but very real amount.
SPINE_FACTOR = {
    "white": 0.002252,           # black & white text, 60# white paper
    "cream": 0.0025,             # black & white text, 60# cream paper
    "premium_color": 0.002347,   # any illustrated / color interior
}

def spine_width(pages, paper):
    return round(pages * SPINE_FACTOR[paper], 4)

print(spine_width(300, "premium_color"))   # 0.704 inches


BLEED = 0.125   # inches of extra bleed on each outer edge, KDP's own spec

def paperback_full_cover_size(trim_w, trim_h, pages, paper):
    spine = spine_width(pages, paper)
    full_width = round(2 * trim_w + spine + 2 * BLEED, 3)
    full_height = round(trim_h + 2 * BLEED, 3)
    return full_width, full_height

print(paperback_full_cover_size(6.0, 9.0, 300, "premium_color"))
# (12.454, 9.25)


trim_w = 6.14
pages = 431
bleed_total = 2 * 0.125

expected_full_width = 13.262
expected_spine = expected_full_width - (2 * trim_w) - bleed_total
print(round(expected_spine, 4))   # 1.012

real_factor = expected_spine / pages
print(round(real_factor, 6))      # 0.002347


HC_WRAP = 0.591          # confirmed correct — height already matched exactly
old_hinge_total = 0.394  # the value that produced the rejected submission

expected_full_width = 14.874
submitted_full_width = 14.686
shortfall = round(expected_full_width - submitted_full_width, 4)
print(shortfall)   # 0.188 -- entirely a width discrepancy

corrected_hinge_total = round(old_hinge_total + shortfall, 4)
print(corrected_hinge_total)   # 0.582 -- the real, corrected constant


import warnings

CALIBRATED_TRIMS = {
    "paperback": [(6.14, 9.21), (6.0, 9.0)],
    "hardcover": [(6.0, 9.0)],
}
CALIBRATION_SLACK = 0.75   # inches — beyond this, treat the result as unverified

def check_calibration(trim_w, trim_h, binding):
    anchors = CALIBRATED_TRIMS.get(binding, [])
    if not anchors:
        return
    nearest = min(anchors, key=lambda a: abs(a[0] - trim_w) + abs(a[1] - trim_h))
    distance = abs(nearest[0] - trim_w) + abs(nearest[1] - trim_h)
    if distance > CALIBRATION_SLACK:
        warnings.warn(
            f"{trim_w}x{trim_h} {binding} is {distance:.2f}in from the nearest "
            f"confirmed size ({nearest[0]}x{nearest[1]}) — treat as unverified "
            f"until a real upload confirms it."
        )
