import sys, math
import numpy as np
import matplotlib; matplotlib.use("Agg")
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon, Rectangle, Arc
from shapely.geometry import box
from shapely.ops import unary_union
sys.path.insert(0, "/opt/dom45/arhitektor/projects/gamburg")
import geom as G
OUT = "/tmp/claude-1000/-opt-dom45-arhitektor/b5407753-d221-46b8-b718-48292f3c19ba/scratchpad/gamburg_interior/plan_gost_kuhnya.png"
F = G.T + G.FIN            # 0.224
fF = G.fF
rng = np.random.default_rng(45)
fmt = lambda v: f"{v:.3f}".replace(".", ",")
u = lambda x: x - F        # от западной грани отделки
v = lambda y: y - F        # от северной грани отделки

fig, ax = plt.subplots(figsize=(15, 19), dpi=200)
ax.set_aspect("equal")
VX0, VX1, VY0, VY1 = -3.2, 7.0, -2.6, 7.5

def tex_wood(x0, y0, x1, y1):
    PX = 100; w, h = x1 - x0, y1 - y0; Wp, Hp = int(w * PX), int(h * PX)
    img = np.ones((Hp, Wp, 3)) * np.array((0.87, 0.81, 0.67))
    for i in range(int(w / 0.14) + 2):
        a, b = int(i * 0.14 * PX), int((i + 1) * 0.14 * PX); y = -rng.uniform(0, 1.5)
        while y < h:
            Ln = rng.uniform(1.0, 2.2); c = 1 + rng.normal(0, 0.025)
            s, e = int(max(0, y) * PX), int(min(h, y + Ln) * PX); img[s:e, a:b] *= c
            if 0 < e < Hp: img[e - 1:e + 1, a:b] *= 0.9
            y += Ln
        img[:, a:a + 1] *= 0.88
    return np.clip(img, 0, 1)
def tex_tile(x0, y0, x1, y1):
    PX = 100; w, h = x1 - x0, y1 - y0; Wp, Hp = int(w * PX), int(h * PX); s = 60
    img = np.ones((Hp, Wp, 3)) * 0.86
    img *= (1 + rng.normal(0, 0.03, (Hp, Wp)))[..., None]
    for i in range(0, Wp, s): img[:, i:i + 2] = 0.74
    for j in range(0, Hp, s): img[j:j + 2, :] = 0.74
    return np.clip(img, 0, 1)
def floor_poly(poly, tex, z):
    x0, y0, x1, y1 = poly.bounds
    im = ax.imshow(tex(x0, y0, x1, y1), extent=(x0, x1, y1, y0), origin="upper", zorder=z, interpolation="bilinear")
    cp = Polygon(list(poly.exterior.coords), transform=ax.transData, fc="none"); ax.add_patch(cp); im.set_clip_path(cp)
floor_poly(G.room_poly("Кухня-гостиная"), tex_wood, 2)
floor_poly(G.room_poly("Кухня"), tex_tile, 2)
# терраса
t = G.TERRACE
ax.add_patch(Rectangle((t[0], t[2]), t[1] - t[0], t[3] - t[2], fc="#cdbfa6", ec="#9a9a95", lw=1, ls=(0, (6, 4)), zorder=1))
ax.text(3.2, -2.15, "ТЕРРАСА", ha="center", va="center", fontsize=16, color="#6d6350", zorder=3)

# стены
WC = "#3b3b3b"
walls = [box(0, 0, G.L, G.W).difference(box(F, F, G.L - F, G.W - F))] + [box(x0, y0, x1, y1) for x0, x1, y0, y1 in G._wall_boxes()]
cuts = []
for w_, tp, c, wd, h, z, *_ in G.OPEN:
    if w_ == "N": cuts.append(box(c - wd / 2, -0.1, c + wd / 2, F + 0.001))
    elif w_ == "W": cuts.append(box(-0.1, c - wd / 2, F + 0.001, c + wd / 2))
for o, pos, c, wd, nm, _ in G.DOORS_IN:
    cuts.append(box(pos - 0.2, c - wd / 2, pos + 0.2, c + wd / 2) if o == "x" else box(c - wd / 2, pos - 0.2, c + wd / 2, pos + 0.2))
wall = unary_union(walls).difference(unary_union(cuts)).intersection(box(VX0, VY0, 6.6, 7.6))
for g in getattr(wall, "geoms", [wall]):
    ax.add_patch(Polygon(list(g.exterior.coords), closed=True, fc=WC, ec=WC, lw=0.5, zorder=5))
ax.text(6.35, 6.1, "→ прихожая /\nтех. пом.", fontsize=11, color="#999", ha="center", va="center", zorder=3)

def window(x0, y0, x1, y1):
    ax.add_patch(Rectangle((x0, y0), x1 - x0, y1 - y0, fc="white", ec="#555", lw=0.8, zorder=6))
    for f in (0.35, 0.65):
        if x1 - x0 > y1 - y0: ax.plot([x0, x1], [y0 + (y1 - y0) * f] * 2, color="#7fb3d5", lw=2, zorder=7)
        else: ax.plot([x0 + (x1 - x0) * f] * 2, [y0, y1], color="#7fb3d5", lw=2, zorder=7)
OP = {}
for w_, tp, c, wd, h, z, nm in G.OPEN:
    if tp == "ДП-05":
        window(c + 0.44 - 0.165, -0.04, c + 0.44 + 0.165, F)            # боковая панель
    elif w_ == "N" and c < 5: window(c - wd / 2, -0.04, c + wd / 2, F)
    elif w_ == "W" and c < 6: window(-0.04, c - wd / 2, F, c + wd / 2)
# полотно ДП-05 внутрь
hx, hy = 1.28, F; jx = 2.16; r = jx - hx - 0.05
ax.plot([hx, hx], [hy, hy + r], color="#333", lw=1.8, zorder=8)
ax.add_patch(Arc((hx, hy), 2 * r, 2 * r, theta1=0, theta2=90, color="#333", lw=1, zorder=8))

# ---------- размерные линии ----------
DC = "#111"
BOX = dict(fc="white", ec="none", boxstyle="square,pad=0.15", alpha=0.92)
def dim(p, q, text, off=0.0, fs=14):
    (x0, y0), (x1, y1) = p, q
    horiz = abs(y1 - y0) < 1e-9
    a, b = ((x0, y0 + off), (x1, y1 + off)) if horiz else ((x0 + off, y0), (x1 + off, y1))
    ax.annotate("", b, a, arrowprops=dict(arrowstyle="<|-|>", lw=1.1, color=DC, mutation_scale=11, shrinkA=0, shrinkB=0), zorder=12)
    ax.plot([x0, a[0]], [y0, a[1]], color=DC, lw=0.5, zorder=12); ax.plot([x1, b[0]], [y1, b[1]], color=DC, lw=0.5, zorder=12)
    ax.text((a[0] + b[0]) / 2, (a[1] + b[1]) / 2, text, ha="center", va="center", rotation=0 if horiz else 90, fontsize=fs, color=DC, zorder=13, bbox=BOX)
# север: цепочка проёмов и общий размер
nx = [F, 1.275, 2.485, 3.785, 4.995, 5.508]
for a, b in zip(nx[:-1], nx[1:]): dim((a, F), (b, F), fmt(b - a), off=-0.5, fs=12.5)
dim((F, F), (5.508, F), fmt(5.508 - F), off=-1.0, fs=15)
# запад: цепочка проёмов и общие размеры
wy = [F, 1.423, 2.595, 4.51, 4.8975, 5.8005, 6.323]
for a, b in zip(wy[:-1], wy[1:]): dim((F, a), (F, b), fmt(b - a), off=-0.55, fs=12.5)
dim((F, F), (F, 4.51), fmt(4.51 - F), off=-1.1, fs=15)
dim((F, 4.51), (F, 6.323), fmt(6.323 - 4.51), off=-1.1, fs=15)
# восток гостиной и проём в коридор
dim((5.508, F), (5.508, 2.927), fmt(2.927 - F), off=0.55, fs=13)
dim((5.02, 3.201), (5.02, 4.373), "1,172", off=0.9, fs=12.5)
# юг гостиной (линия 4,51), цепочка выше линии
for a, b, t in ((F, 2.99, None), (2.99, 3.9, None), (3.9, 4.97, "проход ")):
    dim((a, 4.51), (b, 4.51), fmt(b - a), off=-0.78, fs=12.5)
# кухня
dim((F, 6.323), (3.626, 6.323), fmt(3.626 - F), off=0.95, fs=15)
dim((3.626, 4.647), (3.626, 6.323), fmt(6.323 - 4.647), off=0.75, fs=12.5)

def tag(x, y, s, fs=12, color="#0a4a7a"):
    ax.text(x, y, s, ha="center", va="center", fontsize=fs, color=color, zorder=14, linespacing=1.3, bbox=dict(fc="white", ec=color, lw=0.8, boxstyle="round,pad=0.35"))
tag(1.88, -1.55, "ДП-05 дверь на террасу 1,210\n(полотно 0,88 + панель 0,33)\nпорог 0,00 · проём h 2,06")
tag(4.39, -1.55, "ОП-03 французское окно 1,210\nниз 0,00 · проём h 2,06")
tag(-2.35, 2.009, "ОП-01 окно\n1,172 × 1,730\nниз 0,346\nверх 2,076")
tag(-2.35, 5.349, "ОП-04 окно\n0,903 × 1,730\nниз 0,346\nверх 2,076")

BC = "#b5262a"
def beam(x0, x1, y, hw, label, lx, ly):
    ax.add_patch(Rectangle((x0, y - hw), x1 - x0, 2 * hw, fc=(0.75, 0.15, 0.17, 0.22), ec=BC, lw=1.4, ls=(0, (5, 3)), zorder=9))
    ax.text(lx, ly, label, ha="left", va="center", fontsize=12, color=BC, zorder=14, bbox=dict(fc="white", ec="none", boxstyle="square,pad=0.15", alpha=0.9))
beam(F, 5.508, 2.682, 0.0675, "ПС-1 · низ 2,804", 0.35, 2.52)
beam(F, 5.508, 4.205, 0.0675, "КБ (конёк) · низ 3,317", 0.35, 4.03)
beam(F, 3.626, 4.51, 0.0675, "БК · низ 3,235", 0.35, 4.67)
ax.add_patch(Rectangle((5.02, 3.201), 0.09, 4.373 - 3.201, fc=(0.75, 0.15, 0.17, 0.3), ec=BC, lw=1.4, ls=(0, (5, 3)), zorder=9))
ax.text(5.2, 3.45, "РГ · низ 3,122", ha="left", va="center", fontsize=11.5, color=BC, zorder=14, bbox=dict(fc="white", ec="none", boxstyle="square,pad=0.15", alpha=0.9))
ax.add_patch(Rectangle((1.68, 4.17), 1.5, 0.6, fc="none", ec="#555", lw=1.6, ls=(0, (2, 2)), zorder=9))
ax.text(2.43, 4.40, "«стойка» 1,5×0,6\n(только на плане сайта)", ha="center", va="center", fontsize=9.5, color="#333", zorder=14, bbox=dict(fc="white", ec="none", boxstyle="square,pad=0.1", alpha=0.85))

pts = []
def P(n, x, y, z, t): pts.append((n, x, y, z, t))
P("1", 3.40, 4.373, 0.9, "выключатель 2-кл. (стена К1, у прохода)")
P("2", 5.508, 1.50, 2.4, "бра (стена 4с)")
P("3", 5.508, 2.20, 1.1, "розетка двойная, ТВ (стена 4с)")
P("4", F, 3.50, 0.3, "розетка (запад)")
P("5", F, 2.009, 0.3, "вывод под конвектор ЭК-1 (запад)")
P("6", 3.10, F, 0.3, "вывод под конвектор ЭК-1 (север)")
P("7", 3.15, 4.373, 0.3, "розетка (стена К1, сторона гостиной)")
P("8", 0.90, 6.323, 0.3, "посудомойка")
P("9", 1.80, 6.323, 0.3, "варочная 32 А (+ розетка вытяжки z 2,0)")
P("10", 2.50, 6.323, 1.2, "розетка двойная над столешницей")
P("11", 3.30, 6.323, 0.3, "холодильник")
P("12", F, 5.349, 0.3, "вывод под конвектор ЭК-2 (под окном)")
P("13", 3.626, 5.50, 2.4, "бра кухни (стена 3)")
OFF = {"1": (0, -0.22), "2": (-0.25, 0), "3": (-0.25, 0), "4": (0.25, 0), "5": (0.25, 0), "6": (0, 0.25), "7": (0.2, 0.25),
       "8": (0, -0.25), "9": (0, -0.25), "10": (0, -0.25), "11": (0, -0.25), "12": (0.25, 0), "13": (-0.25, 0)}
for n, x, y, z, t in pts:
    ax.plot(x, y, "o", ms=11, color="#e07b00", mec="white", mew=1.5, zorder=15)
    dx, dy = OFF[n]; ax.text(x + dx, y + dy, n, ha="center", va="center", fontsize=11.5, color="#7a3f00", fontweight="bold", zorder=16, bbox=dict(fc="white", ec="none", boxstyle="circle,pad=0.1", alpha=0.8))
ax.plot([1.27, 1.30, 1.33], [6.10] * 3, "s", ms=6, color="#1a73c8", mec="white", mew=1, zorder=15)
ax.text(1.30, 5.80, "В1·К1·Т3", ha="center", va="center", fontsize=11, color="#0d4f99", fontweight="bold", zorder=16, bbox=dict(fc="white", ec="none", boxstyle="square,pad=0.1", alpha=0.85))
ax.text(2.4, 1.1, "ГОСТИНАЯ", ha="center", va="center", fontsize=22, fontweight="bold", color="#222", zorder=10)
ax.text(2.4, 1.45, "21,76 м²", ha="center", va="center", fontsize=18, color="#222", zorder=10)
ax.text(1.6, 5.0, "КУХНЯ", ha="center", va="center", fontsize=20, fontweight="bold", color="#222", zorder=10)
ax.text(1.6, 5.3, "6,08 м²", ha="center", va="center", fontsize=16, color="#222", zorder=10)

ax.set_xlim(VX0, VX1); ax.set_ylim(7.8, VY0); ax.axis("off")
ax.annotate("С", (6.6, -1.9), (6.6, -1.2), arrowprops=dict(arrowstyle="-|>", lw=2, color="#222"), ha="center", va="bottom", fontsize=16)
leg = ["Размеры — м, по граням отделки; от западной (x) и северной (y) грани отделки гостиной; высоты z — от ЧИСТОГО пола (СИП-пол + 0,068).", "Точки ЭЛ «Эконом» (оранжевые):"]
for n, x, y, z, t in pts:
    leg.append(f"  {n:>2}  {t}:  x {fmt(x - F)}, y {fmt(y - F)}, z {str(z).replace('.', ',')}")
leg.append("  В1 / Т3 / К1 — мойка: x 1,046 / 1,106 / 1,076, y 5,876 (0,22 от южной стены), z 0,55 / 0,55 / 0,45")
leg.append("Проём в коридор 1,172 и проход в прихожую 1,070 — без дверей. Красный пунктир — потолочные элементы, указан низ от чистого пола: ПС-1 ЛВЛ 3×45×300 (y 2,682), КБ 3×45×195 (конёк, y 4,205),")
leg.append("  БК 3×45×195 (y 4,51, x до 3,63), РГ ригель 2×45×195 (x 5,065, y 3,06…4,51). Ширина ПС-1/КБ/БК — 135 мм, РГ — 90 мм.")
fig.text(0.04, 0.235, "\n".join(leg), ha="left", va="top", fontsize=11.5, color="#222", linespacing=1.4)
fig.subplots_adjust(left=0.02, right=0.98, top=0.95, bottom=0.27)
fig.suptitle("Гамбург — гостиная и кухня: чистовые размеры (по отделке, от чистого пола)", fontsize=17, y=0.985)
plt.savefig(OUT, dpi=200, facecolor="white")
from PIL import Image
print(Image.open(OUT).size)
