import React from 'react';
import { useCurrentFrame, useVideoConfig, Sequence } from 'remotion';
import { SLACK } from './lib/slack-colors';
import { SlackHeader } from './components/slack/SlackHeader';
import { SlackMessageRow } from './components/slack/SlackMessageRow';
import { SlackTypingIndicator } from './components/slack/SlackTypingIndicator';
import { SlackInputBar } from './components/slack/SlackInputBar';
import type { SlackMessage, SlackTimedEvent, SlackSender } from './slack-types';

interface SlackScreenProps {
  messages: SlackMessage[];
  timeline: SlackTimedEvent[];
  layout?: 'portrait' | 'landscape';
  channelName?: string;
}

export const SlackScreen: React.FC<SlackScreenProps> = ({
  messages,
  timeline,
  layout = 'portrait',
  channelName,
}) => {
  const frame = useCurrentFrame();
  const { width: compWidth, height: compHeight } = useVideoConfig();

  const isLandscape = layout === 'landscape';

  let panelWidth: number;
  let panelHeight: number;
  if (isLandscape) {
    panelHeight = compHeight * 0.9;
    panelWidth = Math.round(panelHeight * (390 / 844));
  } else {
    panelWidth = compWidth;
    panelHeight = compHeight;
  }

  const scale = panelWidth / 390;

  const messageEvents = timeline.filter((e) => e.type === 'message');
  const typingEvents = timeline.filter((e) => e.type === 'typing');
  const reactionEvents = timeline.filter((e) => e.type === 'reaction');

  const reactionMap = new Map<number, Array<{ reaction: { emoji: string; count: number }; revealFrame: number }>>();
  for (const evt of reactionEvents) {
    if (evt.messageIndex === undefined || evt.reactionIndex === undefined) continue;
    const msg = messages[evt.messageIndex];
    if (!msg?.reactions) continue;
    const reaction = msg.reactions[evt.reactionIndex];
    if (!reaction) continue;
    if (!reactionMap.has(evt.messageIndex)) reactionMap.set(evt.messageIndex, []);
    reactionMap.get(evt.messageIndex)!.push({ reaction, revealFrame: evt.startFrame });
  }

  const activeTyping = typingEvents.find(
    (e) => frame >= e.startFrame && frame < e.startFrame + e.durationFrames
  );

  const content = (
    <div
      style={{
        width: panelWidth,
        height: panelHeight,
        backgroundColor: SLACK.bg,
        display: 'flex',
        flexDirection: 'column',
        overflow: 'hidden',
      }}
    >
      <SlackHeader scale={scale} width={panelWidth} channelName={channelName} />

      <div
        style={{
          flex: 1,
          display: 'flex',
          flexDirection: 'column',
          justifyContent: 'flex-end',
          overflow: 'hidden',
          paddingTop: Math.round(8 * scale),
        }}
      >
        <div style={{ display: 'flex', flexDirection: 'column' }}>
          {messageEvents.map((evt, idx) => {
            if (evt.messageIndex === undefined) return null;
            if (frame < evt.startFrame) return null;

            const msg = messages[evt.messageIndex];

            const prevEvt = idx > 0 ? messageEvents[idx - 1] : null;
            const prevMsg =
              prevEvt && prevEvt.messageIndex !== undefined && frame >= prevEvt.startFrame
                ? messages[prevEvt.messageIndex]
                : null;
            const isConsecutive = prevMsg?.sender === msg.sender;

            const visibleReactions = reactionMap.get(evt.messageIndex) ?? [];

            return (
              <Sequence key={evt.messageIndex} from={evt.startFrame} layout="none">
                <SlackMessageRow
                  message={msg}
                  scale={scale}
                  isConsecutive={isConsecutive}
                  visibleReactions={visibleReactions}
                  currentFrame={frame}
                />
              </Sequence>
            );
          })}

          {activeTyping && activeTyping.typingSender && (
            <SlackTypingIndicator
              sender={activeTyping.typingSender}
              scale={scale}
            />
          )}
        </div>
      </div>

      <SlackInputBar scale={scale} />
    </div>
  );

  if (isLandscape) {
    return (
      <div
        style={{
          width: compWidth,
          height: compHeight,
          backgroundColor: '#111316',
          display: 'flex',
          alignItems: 'center',
          justifyContent: 'center',
        }}
      >
        <div
          style={{
            boxShadow: '0 8px 60px rgba(0,0,0,0.7)',
            borderRadius: Math.round(12 * scale),
            overflow: 'hidden',
          }}
        >
          {content}
        </div>
      </div>
    );
  }

  return content;
};
