import React, { useState } from 'react';
import {
  CHANNEL_WIDTH,
  HOUR_WIDTH,
  MINUTE_BLOCK_WIDTH,
  MINUTE_INCREMENT,
  PROGRAM_HEIGHT,
} from '../utils/guideUtils.js';
import { Box, Flex, Text, Tooltip } from '@mantine/core';
import { Play } from 'lucide-react';
import logo from '../images/logo.png';

// Buffer in pixels beyond the viewport edges to render programs.
// This prevents pop-in when scrolling horizontally.
const H_BUFFER = 600;

const TOTAL_PLACEHOLDERS = Math.ceil(24 / 2);
const PLACEHOLDER_BLOCK_WIDTH = HOUR_WIDTH * 2;

const PlaceholderProgram = React.memo(
  ({ channelId, vpLeft, vpRight, rowHeight }) => {
    return (
      <>
        {Array.from({ length: TOTAL_PLACEHOLDERS }).map(
          (_, placeholderIndex) => {
            const left = placeholderIndex * PLACEHOLDER_BLOCK_WIDTH;
            if (left + PLACEHOLDER_BLOCK_WIDTH < vpLeft || left > vpRight)
              return null;
            return (
              <Box
                key={`placeholder-${channelId}-${placeholderIndex}`}
                style={{
                  alignItems: 'center',
                  justifyContent: 'center',
                }}
                pos="absolute"
                left={left}
                top={0}
                w={PLACEHOLDER_BLOCK_WIDTH}
                h={rowHeight - 4}
                bd={'1px dashed #2D3748'}
                bdrs={4}
                display={'flex'}
                c="#4A5568"
              >
                <Text size="sm">No program data</Text>
              </Box>
            );
          }
        )}
      </>
    );
  }
);

const GuideRow = React.memo(({ index, style, data }) => {
  const {
    filteredChannels,
    programsByChannelId,
    rowHeights,
    logos,
    renderProgram,
    handleLogoClick,
    contentWidth,
    guideScrollLeftRef,
    viewportWidth,
    timelineStartMs,
  } = data;

  const [hovered, setHovered] = useState(false);

  const channel = filteredChannels[index];
  if (!channel) {
    return null;
  }

  const channelPrograms = programsByChannelId.get(channel.id) || [];
  const rowHeight = rowHeights[index] ?? PROGRAM_HEIGHT;

  // Horizontal viewport culling — only render programs whose pixel range
  // overlaps the visible scroll window (plus a buffer to avoid pop-in).
  const scrollLeft = guideScrollLeftRef.current;
  const vpLeft = scrollLeft - H_BUFFER;
  const vpRight = scrollLeft + viewportWidth + H_BUFFER;

  const visiblePrograms = channelPrograms.filter((program) => {
    const leftPx =
      ((program.startMs - timelineStartMs) / 60000 / MINUTE_INCREMENT) *
      MINUTE_BLOCK_WIDTH;
    const durationMin = (program.endMs - program.startMs) / 60000;
    const widthPx = (durationMin / MINUTE_INCREMENT) * MINUTE_BLOCK_WIDTH;
    // Program is visible if its right edge is past vpLeft AND left edge is before vpRight
    return leftPx + widthPx > vpLeft && leftPx < vpRight;
  });

  return (
    <div
      data-testid="guide-row"
      style={{ ...style, width: contentWidth, height: rowHeight }}
    >
      <Box
        style={{
          borderBottom: '0px solid #27272A',
          transition: 'height 0.2s ease',
          overflow: 'visible',
        }}
        display={'flex'}
        h={'100%'}
        pos="relative"
      >
        <Tooltip
          label={channel.name}
          position="right"
          withArrow
          openDelay={400}
          events={{ hover: true, focus: false, touch: false }}
        >
          <Box
            className="channel-logo"
            style={{
              flexShrink: 0,
              alignItems: 'center',
              justifyContent: 'center',
              backgroundColor: '#18181B',
              borderRight: '1px solid #27272A',
              borderBottom: '1px solid #27272A',
              boxShadow: '2px 0 5px rgba(0,0,0,0.2)',
              zIndex: 30,
              transition: 'height 0.2s ease',
              cursor: 'pointer',
            }}
            w={CHANNEL_WIDTH}
            miw={CHANNEL_WIDTH}
            display={'flex'}
            left={0}
            h={'100%'}
            pos="relative"
            onClick={(event) => handleLogoClick(channel, event)}
            onMouseEnter={() => setHovered(true)}
            onMouseLeave={() => setHovered(false)}
          >
            {hovered && (
              <Flex
                align="center"
                justify="center"
                style={{
                  backgroundColor: 'rgba(0, 0, 0, 0.7)',
                  zIndex: 10,
                  animation: 'fadeIn 0.2s',
                }}
                pos="absolute"
                top={0}
                left={0}
                right={0}
                bottom={0}
                w={'100%'}
                h={'100%'}
              >
                <Play size={32} color="#fff" fill="#fff" />
              </Flex>
            )}

            <Flex
              align="center"
              justify="center"
              style={{
                boxSizing: 'border-box',
                zIndex: 5,
              }}
              w={'100%'}
              h={'100%'}
              p={'4px'}
              pos="relative"
            >
              <Box
                style={{
                  alignItems: 'center',
                  justifyContent: 'center',
                  overflow: 'hidden',
                  backgroundColor: 'rgba(255,255,255,0.09)',
                  borderRadius: 6,
                }}
                w={'100%'}
                h={`${rowHeight - 12}px`}
                display={'flex'}
                p={'4px 6px 14px 6px'}
              >
                <img
                  src={logos[channel.logo_id]?.cache_url || logo}
                  alt={channel.name}
                  style={{
                    maxWidth: '100%',
                    maxHeight: '100%',
                    objectFit: 'contain',
                  }}
                />
              </Box>

              <Text
                size="xs"
                fw={600}
                style={{
                  backgroundColor: '#18181B',
                  alignItems: 'center',
                  justifyContent: 'center',
                  borderRadius: 6,
                }}
                pos="absolute"
                bottom={6}
                right={6}
                p={'1px 4px'}
                bd={'1px solid #27272A'}
                h={'20px'}
                display={'flex'}
                fz={'0.75em'}
              >
                {channel.channel_number || '-'}
              </Text>
            </Flex>
          </Box>
        </Tooltip>

        <Box
          style={{
            transition: 'height 0.2s ease',
          }}
          flex={1}
          pos="relative"
          h={'100%'}
          pl={0}
        >
          {visiblePrograms.length > 0 ? (
            visiblePrograms.map((program) =>
              renderProgram(program, undefined, channel)
            )
          ) : channelPrograms.length > 0 ? null : (
            <PlaceholderProgram
              channelId={channel.id}
              vpLeft={vpLeft}
              vpRight={vpRight}
              rowHeight={rowHeight}
            />
          )}
        </Box>
      </Box>
    </div>
  );
});

export default GuideRow;
