import React, { useMemo } from 'react';

import {
  Layer,
  Rect,
  Stage,
  Text,
} from 'react-konva';

import {
  HallElementType,
  HallType,
  TypeSTWZEnum,
} from '@/api/types';

import {
  getHallBlockCornerRadius,
  getHallBlockOnShapeTextFill,
  HALL_LABELS,
  HALL_SECTOR,
  HALL_STAGE_SIZE,
  resolveHallElementFill,
} from './hallTheme';

type DialogHallPreviewProps = {
    hall: HallType | null;
    width: number;
    height: number;
};

function partitionElements(elements: HallElementType[]) {
    const sectors = elements.filter((e) => e.type === 'sector' || e.type === 'zone');
    const rects = elements.filter((e) => e.type !== 'sector' && e.type !== 'zone');
    return { sectors, rects };
}

const DialogHallPreview = (props: DialogHallPreviewProps) => {
    const { hall, width, height } = props;

    const elements = hall?.elements ?? [];
    const { sectors, rects } = useMemo(() => partitionElements(elements), [elements]);

    const scale = useMemo(() => {
        const w = Math.max(1, width);
        const h = Math.max(1, height);
        return Math.min(w / HALL_STAGE_SIZE, h / HALL_STAGE_SIZE);
    }, [width, height]);

    const stageCssW = HALL_STAGE_SIZE * scale;
    const stageCssH = HALL_STAGE_SIZE * scale;
    const offsetX = (width - stageCssW) / 2;
    const offsetY = (height - stageCssH) / 2;

    return (
        <div
            className="relative overflow-hidden rounded-md bg-white outline-1 outline-slate-300"
            style={{ width, height }}
        >
            <div
                className="absolute"
                style={{
                    left: offsetX,
                    top: offsetY,
                    width: stageCssW,
                    height: stageCssH,
                }}
            >
                <Stage
                    width={HALL_STAGE_SIZE}
                    height={HALL_STAGE_SIZE}
                    scaleX={scale}
                    scaleY={scale}
                    listening={false}
                >
                    <Layer listening={false}>
                        {sectors.map((item) => (
                            <React.Fragment key={item.id}>
                                <Rect
                                    x={item.x}
                                    y={item.y}
                                    width={item.width}
                                    height={item.height}
                                    rotation={item.rotation}
                                    fill={HALL_SECTOR.fill}
                                    stroke={HALL_SECTOR.stroke}
                                    strokeWidth={HALL_SECTOR.strokeWidth}
                                    cornerRadius={getHallBlockCornerRadius(item.type as TypeSTWZEnum)}
                                    listening={false}
                                />
                                <Text
                                    x={item.x}
                                    y={item.type === 'zone' ? (item.y + item.height / 2 - 8) : (item.y - 22)}
                                    width={item.width}
                                    align="center"
                                    text={item.label}
                                    fontSize={item.type === 'zone' ? 16 : 14}
                                    fill={item.type === 'zone' ? HALL_SECTOR.labelNoSeats : HALL_SECTOR.labelRegular}
                                    listening={false}
                                />
                                {item.type === 'zone' && (
                                    <Text
                                        x={item.x}
                                        y={item.y + item.height / 2 + 12}
                                        width={item.width}
                                        align="center"
                                        text={`Вместимость: ${Math.max(0, Math.floor(Number(item.capacity ?? 0) || 0))} человек`}
                                        fontSize={12}
                                        fill={HALL_SECTOR.capacityText}
                                        listening={false}
                                    />
                                )}
                            </React.Fragment>
                        ))}
                    </Layer>

                    <Layer listening={false}>
                        {rects.map((item) => (
                            <React.Fragment key={item.id}>
                                <Rect
                                    x={item.x}
                                    y={item.y}
                                    width={item.width}
                                    height={item.height}
                                    rotation={item.rotation}
                                    fill={resolveHallElementFill(item, hall?.belts)}
                                    cornerRadius={getHallBlockCornerRadius(item.type as TypeSTWZEnum)}
                                    listening={false}
                                />
                                <Text
                                    x={item.x - 18}
                                    y={item.y + item.height / 2 - 6}
                                    width={16}
                                    align="right"
                                    text={item.type === 'seat' ? (item.seatRow ?? '') : ''}
                                    fontSize={12}
                                    fill={HALL_LABELS.seatRow}
                                    listening={false}
                                    visible={item.type === 'seat' && Boolean(item.seatRow)}
                                />
                                <Text
                                    x={item.type === 'seat' ? item.x : item.x + 6}
                                    y={item.type === 'seat' ? item.y + item.height / 2 - 6 : item.y + 6}
                                    width={item.type === 'seat' ? item.width : undefined}
                                    align={item.type === 'seat' ? 'center' : undefined}
                                    text={
                                        item.type === 'seat'
                                            ? (item.seatNumber ?? '')
                                            : (item.type === 'wall' ? '' : item.label)
                                    }
                                    fontSize={12}
                                    fill={getHallBlockOnShapeTextFill(item.type as TypeSTWZEnum)}
                                    listening={false}
                                    visible={
                                        (item.type !== 'seat' && item.type !== 'stage')
                                        || Boolean(item.seatNumber)
                                    }
                                />
                                <Text
                                    x={item.x}
                                    y={item.y + item.height / 2 - 8}
                                    width={item.width}
                                    align="center"
                                    text={item.type === 'stage' ? item.label : ''}
                                    fontSize={16}
                                    fill={getHallBlockOnShapeTextFill('stage')}
                                    listening={false}
                                    visible={item.type === 'stage'}
                                />
                            </React.Fragment>
                        ))}
                    </Layer>
                </Stage>
            </div>
        </div>
    );
};

export default DialogHallPreview;
