/** Раскладка подписи сектора/зоны у визуально верхнего ребра. */

export type HallSectorLabelLayout = {
    x: number;
    y: number;
    rotation: number;
    width: number;
    offsetX: number;
    offsetY: number;
    fontSize: number;
};

type Point = { x: number; y: number };

function rotateLocalPoint(
    originX: number,
    originY: number,
    localX: number,
    localY: number,
    rotationDeg: number,
): Point {
    const rad = (rotationDeg * Math.PI) / 180;
    const cos = Math.cos(rad);
    const sin = Math.sin(rad);
    return {
        x: originX + localX * cos - localY * sin,
        y: originY + localX * sin + localY * cos,
    };
}

function readableEdgeAngleDeg(dx: number, dy: number): number {
    let angle = (Math.atan2(dy, dx) * 180) / Math.PI;
    if (angle > 90) {
        angle -= 180;
    }
    if (angle <= -90) {
        angle += 180;
    }
    return angle;
}

/**
 * Подпись у ребра с минимальным midY (визуальный «верх» AABB по рёбрам),
 * вдоль наклона ребра; угол нормализуется, чтобы текст читался.
 * Координаты как у Konva.Rect: (x,y) = левый верх, rotation вокруг (x,y).
 */
export function hallSectorLabelLayout(params: {
    x: number;
    y: number;
    width: number;
    height: number;
    rotation?: number;
    fontSize?: number;
    gap?: number;
}): HallSectorLabelLayout {
    const w = Number.isFinite(params.width) && params.width > 0 ? params.width : 1;
    const h = Number.isFinite(params.height) && params.height > 0 ? params.height : 1;
    const rotation = params.rotation ?? 0;
    const fontSize = params.fontSize ?? 14;
    const gap = params.gap ?? Math.max(10, Math.round(fontSize * 0.85));

    const corners: Point[] = [
        rotateLocalPoint(params.x, params.y, 0, 0, rotation),
        rotateLocalPoint(params.x, params.y, w, 0, rotation),
        rotateLocalPoint(params.x, params.y, w, h, rotation),
        rotateLocalPoint(params.x, params.y, 0, h, rotation),
    ];

    const edgePairs: Array<[number, number]> = [
        [0, 1],
        [1, 2],
        [2, 3],
        [3, 0],
    ];

    let best: {
        a: Point;
        b: Point;
        midX: number;
        midY: number;
        len: number;
    } | null = null;

    for (const [i, j] of edgePairs) {
        const a = corners[i]!;
        const b = corners[j]!;
        const midX = (a.x + b.x) / 2;
        const midY = (a.y + b.y) / 2;
        const len = Math.hypot(b.x - a.x, b.y - a.y);
        if (
            !best
            || midY < best.midY - 1e-6
            || (Math.abs(midY - best.midY) <= 1e-6 && len > best.len)
        ) {
            best = { a, b, midX, midY, len };
        }
    }

    const edge = best!;
    const centerX = corners.reduce((sum, p) => sum + p.x, 0) / 4;
    const centerY = corners.reduce((sum, p) => sum + p.y, 0) / 4;
    let nx = edge.midX - centerX;
    let ny = edge.midY - centerY;
    const nLen = Math.hypot(nx, ny) || 1;
    nx /= nLen;
    ny /= nLen;

    const labelWidth = Math.max(48, edge.len * 0.92);
    const angle = readableEdgeAngleDeg(edge.b.x - edge.a.x, edge.b.y - edge.a.y);

    return {
        x: edge.midX + nx * gap,
        y: edge.midY + ny * gap,
        rotation: angle,
        width: labelWidth,
        offsetX: labelWidth / 2,
        offsetY: fontSize / 2,
        fontSize,
    };
}
