// Read-only floor plan renderer shared by the dashboard /seating page and
// the public seat-finder. Tables match by case-insensitive label trim —
// the same convention the public floor-plan endpoint uses.

export type FloorElementType =
    | 'round_table' | 'rect_table' | 'sweetheart_table' | 'buffet_table' | 'gift_table'
    | 'cake_table' | 'dance_floor' | 'dj_booth' | 'stage' | 'bar' | 'lounge'
    | 'photo_booth' | 'altar' | 'arch';

export interface FloorElement {
    id: string;
    type: FloorElementType;
    x: number;
    y: number;
    width: number;
    height: number;
    rotation: number;
    label: string;
    seats?: number;
}

export interface PublicFloorPlan {
    id: string;
    name: string;
    room_width: number;
    room_height: number;
    elements: FloorElement[];
}

const PPM = 40;
const ROUND_TYPES = new Set<FloorElementType>(['round_table', 'sweetheart_table']);
const ZONE_TYPES  = new Set<FloorElementType>([
    'dance_floor', 'dj_booth', 'stage', 'bar', 'lounge', 'photo_booth', 'altar', 'arch',
]);

// Zone fills — match the builder's palette so the layout still reads at
// a glance, while tables use the editorial cream/charcoal.
const ZONE_FILL: Partial<Record<FloorElementType, string>> = {
    dance_floor: '#e8e0f5',
    dj_booth:    '#202023',
    stage:       '#dde8da',
    bar:         '#3a2a2a',
    lounge:      '#f0e5dd',
    photo_booth: '#f9f5e8',
    altar:       '#fff7ec',
    arch:        '#fae6e8',
};

export function FloorPlanView({
    plan,
    highlightTable,
    accent,
    className,
}: {
    plan: PublicFloorPlan;
    highlightTable: string | null;
    accent: string;
    className?: string;
}) {
    const target = highlightTable ? highlightTable.trim().toLowerCase() : null;
    const elements = plan.elements ?? [];
    const width = (plan.room_width || 10) * PPM;
    const height = (plan.room_height || 6) * PPM;
    const hasHighlight = !!target;

    // Empty floor plan — graceful empty state instead of a crash
    if (elements.length === 0) {
        return (
            <div className={`rounded-2xl border border-border p-10 text-center bg-muted/30 ${className ?? ''}`}>
                <p className="text-[10.5px] tracking-[0.3em] uppercase text-muted-foreground">
                    Floor plan in progress
                </p>
                <p className="font-serif italic text-foreground/70 text-[1.05rem] mt-2">
                    The couple hasn't laid out the room yet.
                </p>
            </div>
        );
    }

    return (
        <div
            className={`rounded-2xl border border-border overflow-hidden ${className ?? ''}`}
            style={{ backgroundColor: 'var(--color-muted)' }}
        >
            <svg
                viewBox={`0 0 ${width} ${height}`}
                className="w-full h-auto"
                preserveAspectRatio="xMidYMid meet"
                role="img"
                aria-label={`Floor plan${highlightTable ? `, with ${highlightTable} highlighted` : ''}`}
                // `color` makes `currentColor` resolve to the active theme's
                // foreground — keeps the grid + outlines visible in both
                // light and dark mode without a per-mode color override.
                style={{ color: 'var(--color-foreground)' }}
            >
                <defs>
                    <pattern id="fp-dotgrid" width="14" height="14" patternUnits="userSpaceOnUse">
                        <circle cx="1" cy="1" r="0.8" fill="currentColor" fillOpacity="0.10" />
                    </pattern>
                </defs>

                {/* Dot grid background — theme-aware via currentColor */}
                <rect width={width} height={height} fill="url(#fp-dotgrid)" />

                {/* Dashed room outline */}
                <rect
                    x="0.5"
                    y="0.5"
                    width={width - 1}
                    height={height - 1}
                    fill="none"
                    stroke="currentColor"
                    strokeOpacity="0.18"
                    strokeWidth="1"
                    strokeDasharray="6 5"
                />

                {elements.map((el) => {
                    const cx = el.x * PPM + (el.width * PPM) / 2;
                    const cy = el.y * PPM + (el.height * PPM) / 2;
                    const pw = el.width * PPM;
                    const ph = el.height * PPM;
                    const isMatch = !!target && el.label.trim().toLowerCase() === target;
                    const isZone = ZONE_TYPES.has(el.type);
                    const dim = hasHighlight && !isMatch;

                    const fill = isMatch
                        ? 'var(--color-foreground)'
                        : isZone
                            ? (ZONE_FILL[el.type] ?? 'var(--color-card)')
                            : 'var(--color-card)';
                    const stroke = isMatch ? accent : 'currentColor';
                    const strokeOpacity = isMatch ? 1 : (isZone ? 0.28 : 0.35);
                    const sw = isMatch ? 2 : 1;
                    const opacity = dim ? 0.32 : 1;

                    return (
                        <g
                            key={el.id}
                            transform={`rotate(${el.rotation}, ${cx}, ${cy})`}
                            opacity={opacity}
                        >
                            {/* Halo behind matched table */}
                            {isMatch && (ROUND_TYPES.has(el.type) ? (
                                <ellipse
                                    cx={cx}
                                    cy={cy}
                                    rx={pw / 2 + 14}
                                    ry={ph / 2 + 14}
                                    fill="none"
                                    stroke={accent}
                                    strokeWidth="2"
                                    opacity="0.35"
                                />
                            ) : (
                                <rect
                                    x={el.x * PPM - 8}
                                    y={el.y * PPM - 8}
                                    width={pw + 16}
                                    height={ph + 16}
                                    rx="6"
                                    fill="none"
                                    stroke={accent}
                                    strokeWidth="2"
                                    opacity="0.35"
                                />
                            ))}

                            {ROUND_TYPES.has(el.type) ? (
                                <ellipse
                                    cx={cx}
                                    cy={cy}
                                    rx={pw / 2}
                                    ry={ph / 2}
                                    fill={fill}
                                    stroke={stroke}
                                    strokeOpacity={strokeOpacity}
                                    strokeWidth={sw}
                                />
                            ) : (
                                <rect
                                    x={el.x * PPM}
                                    y={el.y * PPM}
                                    width={pw}
                                    height={ph}
                                    rx={el.type === 'dance_floor' || el.type === 'lounge' ? 6 : 3}
                                    fill={fill}
                                    stroke={stroke}
                                    strokeOpacity={strokeOpacity}
                                    strokeWidth={sw}
                                />
                            )}

                            {/* Seat dots — round tables */}
                            {el.seats && el.type === 'round_table' &&
                                Array.from({ length: el.seats }).map((_, i) => {
                                    const seats = el.seats ?? 1;
                                    const angle = (i / seats) * Math.PI * 2 - Math.PI / 2;
                                    const dotCx = cx + Math.cos(angle) * (pw / 2 + 7);
                                    const dotCy = cy + Math.sin(angle) * (pw / 2 + 7);
                                    return (
                                        <circle
                                            key={i}
                                            cx={dotCx}
                                            cy={dotCy}
                                            r="4"
                                            fill={isMatch ? accent : 'var(--color-card)'}
                                            stroke={isMatch ? accent : 'currentColor'}
                                            strokeOpacity={isMatch ? 1 : 0.40}
                                            strokeWidth="1"
                                        />
                                    );
                                })}

                            {/* Seat dots — rect tables (top + bottom edges) */}
                            {el.seats && el.type !== 'round_table' && el.type !== 'sweetheart_table' &&
                                Array.from({ length: Math.floor((el.seats ?? 0) / 2) }).map((_, i) => {
                                    const half = Math.floor((el.seats ?? 0) / 2);
                                    const gap = pw / (half + 1);
                                    return (
                                        <g key={i}>
                                            <circle cx={el.x * PPM + gap * (i + 1)} cy={el.y * PPM - 7}              r="4" fill="var(--color-card)" stroke="currentColor" strokeOpacity="0.40" strokeWidth="1" />
                                            <circle cx={el.x * PPM + gap * (i + 1)} cy={(el.y + el.height) * PPM + 7} r="4" fill="var(--color-card)" stroke="currentColor" strokeOpacity="0.40" strokeWidth="1" />
                                        </g>
                                    );
                                })}

                            <text
                                x={cx}
                                y={cy + 4}
                                textAnchor="middle"
                                fontSize={Math.min(12, pw / (el.label.length * 0.6 + 1))}
                                // Matched table renders on a foreground-coloured fill, so use the
                                // theme's background colour for contrast. Unmatched tables sit on
                                // a card-coloured fill, so use foreground with reduced opacity.
                                fill={isMatch ? 'var(--color-background)' : 'currentColor'}
                                fillOpacity={isMatch ? 1 : 0.75}
                                fontWeight={isMatch ? 600 : 500}
                                style={{ userSelect: 'none', pointerEvents: 'none', letterSpacing: 0.2 }}
                            >
                                {el.label}
                            </text>
                        </g>
                    );
                })}
            </svg>
        </div>
    );
}
