import { ResolutionPropsValue, WindProps, windProps } from "./mapConsts";
import { drawRotatedImage, getAngleFromString } from "./windAngles";
import { faktiskaMarkerLayout, FaktiskaStation } from "../../pages/map-graphics/faktiskaConfig";

// cityName, {x, y}, weatherValue, icon
export type CityData = [cityName: string, {x: number, y: number }, weatherValue: number, icon: string | undefined]

export function drawOnMap(
    ctx: CanvasRenderingContext2D,
    imgArr: [HTMLImageElement, HTMLImageElement],
    cityData: CityData[],
    windData: [string, string, string, boolean, WindProps],
    overlayData: [string, string],
    props: ResolutionPropsValue,
    productionTemplate = false,
): void {
    const [windDirection, windSpeed, windGusts, roundValues, windProp] = windData;
    const [bgImg, arrowImg] = imgArr;
    const [title, source] = overlayData;

    // bg
    ctx.drawImage(bgImg, 0, 0);

    // City value badges use a consistent height and expand horizontally to fit the value.
    cityData.forEach(([, {x, y}, value]) => {
        const localX = props.offsetX + x * props.scale;
        const localY = props.offsetY + y * props.scale;
        const numericValue = roundValues ? Math.round(value) : value.toFixed(1);
        const stringValue = numericValue.toString().replace(".", ",");

        ctx.font = `bold ${props.fontSize}px Monda`;
        const badgeWidth = getBadgeWidth(ctx, stringValue, props);
        ctx.fillStyle = "#FFFFFF";
        ctx.fillRect(localX - badgeWidth / 2, localY - props.boxSize / 2, badgeWidth, props.boxSize);
    });

    // weather values
    cityData.forEach(([city, {x, y}, value, icon]) => {
        const localX = props.offsetX + x * props.scale;
        const localY = props.offsetY + y * props.scale;

        ctx.font = `bold ${props.fontSize}px Monda`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillStyle = "#000000";
        const numericValue = roundValues ? Math.round(value) : value.toFixed(1);
        const stringValue = numericValue.toString().replace(".", ",");
        ctx.fillText(stringValue, localX, localY);

        if (icon) {
            ctx.fillStyle = "#FFFFFF";
            ctx.font = `normal ${props.fontSize * (productionTemplate ? 4.2 : 5)}px Daira by LTV grafika`;
            const iconMetrics = ctx.measureText(icon);
            const glyphWidth = iconMetrics.actualBoundingBoxLeft + iconMetrics.actualBoundingBoxRight;
            const badgeWidth = getBadgeWidth(ctx, stringValue, props, true);

            if (productionTemplate) {
                const layout = faktiskaMarkerLayout[city as FaktiskaStation];
                const side = layout?.iconSide ?? "right";
                const gap = layout?.iconGap ?? 22;
                const offsetX = layout?.iconOffsetX ?? 0;
                const offsetY = layout?.iconOffsetY ?? 0;
                const iconCenterX = side === "right"
                    ? localX + badgeWidth / 2 + gap + glyphWidth / 2 + offsetX
                    : localX - badgeWidth / 2 - gap - glyphWidth / 2 + offsetX;
                drawOpticallyCenteredGlyph(ctx, icon, iconCenterX, localY + offsetY);
            } else {
                drawOpticallyCenteredGlyph(ctx, icon, localX + props.boxSize / 2 + 10 + iconMetrics.width / 2, localY);
            }
        }
    });

    drawTitleOverlay(ctx, title, source, props.width);

    if (!props.showWind) return;

    // wind values
    ctx.font = `bold ${props.windFontSize}px Monda`;
    ctx.textAlign = "left";
    ctx.textBaseline = "top";
    ctx.fillStyle = "#FFFFFF";
    const boxMiddleX = 1675;

    const directionWidth = ctx.measureText(windDirection).width;
    ctx.fillText(windDirection, windProp.offsetX + boxMiddleX - directionWidth / 2 + 30, (windProp.offsetY + 370)*windProp.scaleY);
    const angleInDegrees = getAngleFromString(windDirection);
    drawRotatedImage(ctx, arrowImg, windProp.offsetX + boxMiddleX - directionWidth / 2 - 30, (windProp.offsetY + 370)*windProp.scaleY, angleInDegrees);

    const speedWidth = ctx.measureText(windSpeed).width;
    ctx.fillText(windSpeed, windProp.offsetX + boxMiddleX - speedWidth / 2 - 30, (windProp.offsetY + 575)*windProp.scaleY);
    ctx.font = "bold 25px Monda";
    ctx.fillText("M/S", windProp.offsetX + boxMiddleX + speedWidth / 2 - 22, (windProp.offsetY + 590)*windProp.scaleY);

    ctx.font = `bold ${props.windFontSize}px Monda`;
    const gustsWidth = ctx.measureText(windGusts).width;
    ctx.fillText(windGusts, windProp.offsetX + boxMiddleX - gustsWidth / 2 - 30, (windProp.offsetY + 790)*windProp.scaleY);
    ctx.font = "bold 25px Monda";
    ctx.fillText("M/S", windProp.offsetX + boxMiddleX + gustsWidth / 2 - 22, (windProp.offsetY + 805)*windProp.scaleY);
}

function getBadgeWidth(ctx: CanvasRenderingContext2D, value: string, props: ResolutionPropsValue, restoreValueFont = false): number {
    if (restoreValueFont) ctx.font = `bold ${props.fontSize}px Monda`;
    const width = Math.max(props.boxSize, Math.ceil(ctx.measureText(value).width + props.fontSize * 0.8));
    if (restoreValueFont) ctx.font = `normal ${props.fontSize * 4.2}px Daira by LTV grafika`;
    return width;
}

function drawOpticallyCenteredGlyph(ctx: CanvasRenderingContext2D, glyph: string, centerX: number, centerY: number): void {
    const metrics = ctx.measureText(glyph);
    ctx.textAlign = "left";
    ctx.textBaseline = "alphabetic";
    const x = centerX + (metrics.actualBoundingBoxLeft - metrics.actualBoundingBoxRight) / 2;
    const y = centerY + (metrics.actualBoundingBoxAscent - metrics.actualBoundingBoxDescent) / 2;
    ctx.fillText(glyph, x, y);
}

function drawTitleOverlay(ctx: CanvasRenderingContext2D, title: string, source: string, canvasWidth: number): void {
    if (!title.trim() && !source.trim()) return;

    const scale = canvasWidth / 1920;
    const right = 34 * scale;
    const top = 38 * scale;
    const horizontalPadding = 24 * scale;
    const titleHeight = 62 * scale;
    const sourceHeight = 38 * scale;

    ctx.textAlign = "left";
    ctx.textBaseline = "middle";
    ctx.font = `bold ${30 * scale}px Monda`;
    const titleText = title.trim().toUpperCase();
    const titleWidth = ctx.measureText(titleText).width + horizontalPadding * 2;
    const titleX = canvasWidth - right - titleWidth;

    ctx.fillStyle = "#9b0008";
    ctx.fillRect(titleX, top, titleWidth, titleHeight);
    ctx.fillStyle = "#FFFFFF";
    ctx.fillText(titleText, titleX + horizontalPadding, top + titleHeight / 2);

    if (source.trim()) {
        ctx.font = `bold ${19 * scale}px Monda`;
        const sourceText = source.trim().toUpperCase();
        const sourceWidth = ctx.measureText(sourceText).width + horizontalPadding * 2;
        const sourceX = canvasWidth - right - sourceWidth;
        ctx.fillStyle = "#FFFFFF";
        ctx.fillRect(sourceX, top + titleHeight, sourceWidth, sourceHeight);
        ctx.fillStyle = "#000000";
        ctx.fillText(sourceText, sourceX + horizontalPadding, top + titleHeight + sourceHeight / 2);
    }
}
