"use client";
import Modal from "../modal";
import useTopics from "../useTopics";
import useWaveform from "../useWaveform";
import useMp3 from "../useMp3";
import useParticipants from "../useParticipants";
import { TopicList } from "./_components/TopicList";
import { TranscriptWithGutter } from "./_components/TranscriptWithGutter";
import { Topic } from "../webSocketTypes";
import React, { useEffect, useState, use } from "react";
import FinalSummary from "./finalSummary";
import TranscriptTitle from "../transcriptTitle";
import Player from "../player";
import { useRouter } from "next/navigation";
import {
  Box,
  Flex,
  Grid,
  GridItem,
  Skeleton,
  Text,
  Spinner,
} from "@chakra-ui/react";
import { useTranscriptGet } from "../../../lib/apiHooks";
import { TranscriptStatus } from "../../../lib/transcript";

type TranscriptDetails = {
  params: Promise<{
    transcriptId: string;
  }>;
};

export default function TranscriptDetails(details: TranscriptDetails) {
  const params = use(details.params);
  const transcriptId = params.transcriptId;
  const router = useRouter();
  const statusToRedirect = [
    "idle",
    "recording",
    "processing",
    "uploaded",
  ] satisfies TranscriptStatus[] as TranscriptStatus[];

  const transcript = useTranscriptGet(transcriptId);
  const waiting =
    transcript.data && statusToRedirect.includes(transcript.data.status);

  const mp3 = useMp3(transcriptId, waiting);
  const topics = useTopics(transcriptId);
  const participants = useParticipants(transcriptId);
  const waveform = useWaveform(
    transcriptId,
    waiting || mp3.audioDeleted === true,
  );
  const useActiveTopic = useState<Topic | null>(null);
  const [activeTopic, setActiveTopic] = useActiveTopic;
  const [finalSummaryElement, setFinalSummaryElement] =
    useState<HTMLDivElement | null>(null);

  // IntersectionObserver for active topic detection based on scroll position
  useEffect(() => {
    if (!topics.topics || topics.topics.length === 0) return;

    const observer = new IntersectionObserver(
      (entries) => {
        // Find the most visible segment
        let mostVisibleEntry: IntersectionObserverEntry | null = null;
        let maxRatio = 0;

        entries.forEach((entry) => {
          if (entry.isIntersecting && entry.intersectionRatio > maxRatio) {
            maxRatio = entry.intersectionRatio;
            mostVisibleEntry = entry;
          }
        });

        if (mostVisibleEntry) {
          // Extract topicId from segment id (format: "segment-{topicId}-{idx}")
          const segmentId = mostVisibleEntry.target.id;
          const match = segmentId.match(/^segment-([^-]+)-/);
          if (match) {
            const topicId = match[1];
            const topic = topics.topics?.find((t) => t.id === topicId);
            if (topic && activeTopic?.id !== topic.id) {
              setActiveTopic(topic);
            }
          }
        }
      },
      {
        threshold: [0, 0.25, 0.5, 0.75, 1],
        rootMargin: "-20% 0px -20% 0px",
      },
    );

    // Observe all segment elements
    const segments = document.querySelectorAll('[id^="segment-"]');
    segments.forEach((segment) => observer.observe(segment));

    return () => observer.disconnect();
  }, [topics.topics, activeTopic?.id, setActiveTopic]);

  // Scroll handlers for bidirectional navigation
  const handleTopicClick = (topicId: string) => {
    // Scroll to first segment of this topic in transcript
    const firstSegment = document.querySelector(`[id^="segment-${topicId}-"]`);
    if (firstSegment) {
      firstSegment.scrollIntoView({
        behavior: "smooth",
        block: "center",
      });
    }
  };

  const handleGutterClick = (topicId: string) => {
    // Scroll to topic in list
    const topicChip = document.getElementById(`topic-${topicId}`);
    if (topicChip) {
      topicChip.scrollIntoView({
        behavior: "smooth",
        block: "center",
      });
    }
  };

  const getSpeakerName = (speakerNumber: number) => {
    if (!participants.response) return `Speaker ${speakerNumber}`;
    return (
      participants.response.find(
        (participant) => participant.speaker == speakerNumber,
      )?.name || `Speaker ${speakerNumber}`
    );
  };

  useEffect(() => {
    if (!waiting || !transcript.data) return;

    const status = transcript.data.status;
    let newUrl: string | null = null;

    if (status === "processing" || status === "uploaded") {
      newUrl = `/transcripts/${params.transcriptId}/processing`;
    } else if (status === "recording") {
      newUrl = `/transcripts/${params.transcriptId}/record`;
    } else if (status === "idle") {
      newUrl =
        transcript.data.source_kind === "file"
          ? `/transcripts/${params.transcriptId}/upload`
          : `/transcripts/${params.transcriptId}/record`;
    }

    if (newUrl) {
      // Shallow redirection does not work on NextJS 13
      // https://github.com/vercel/next.js/discussions/48110
      // https://github.com/vercel/next.js/discussions/49540
      router.replace(newUrl);
    }
  }, [waiting, transcript.data?.status, transcript.data?.source_kind]);

  if (waiting) {
    return (
      <Box>
        <Box
          w="full"
          background="gray.bg"
          border={"2px solid"}
          borderColor={"gray.bg"}
          borderRadius={8}
          p={6}
          minH="100%"
          display="flex"
          alignItems="center"
          justifyContent="center"
        >
          <Flex direction="column" align="center" gap={3}>
            <Spinner size="xl" color="blue.500" />
            <Text color="gray.600" textAlign="center">
              Loading transcript...
            </Text>
          </Flex>
        </Box>
      </Box>
    );
  }

  if (transcript.error || topics?.error) {
    return (
      <Modal
        title="Transcription Not Found"
        text="A trascription with this ID does not exist."
      />
    );
  }

  if (transcript?.isLoading || topics?.loading) {
    return <Modal title="Loading" text={"Loading transcript..."} />;
  }

  return (
    <>
      <Grid
        templateColumns="1fr"
        templateRows="auto minmax(0, 1fr)"
        gap={4}
        mt={4}
        mb={4}
      >
        {!mp3.audioDeleted && (
          <>
            {waveform.waveform && mp3.media && topics.topics ? (
              <Player
                topics={topics?.topics}
                useActiveTopic={useActiveTopic}
                waveform={waveform.waveform}
                media={mp3.media}
                mediaDuration={transcript.data?.duration || null}
              />
            ) : !mp3.loading && (waveform.error || mp3.error) ? (
              <Box p={4} bg="red.100" borderRadius="md">
                <Text>
                  Error loading{" "}
                  {[waveform.error && "waveform", mp3.error && "mp3"]
                    .filter(Boolean)
                    .join(" and ")}
                </Text>
              </Box>
            ) : (
              <Skeleton h={14} />
            )}
          </>
        )}
        <Flex
          direction="column"
          gap={4}
          padding={4}
          paddingBottom={0}
          background="gray.bg"
          border="2px solid"
          borderColor="gray.bg"
          borderRadius={8}
        >
          {/* Title */}
          <Flex direction="column" gap={0}>
            <Flex alignItems="center" gap={2}>
              <TranscriptTitle
                title={transcript.data?.title || "Unnamed Transcript"}
                transcriptId={transcriptId}
                onUpdate={() => {
                  transcript.refetch().then(() => {});
                }}
                transcript={transcript.data || null}
                topics={topics.topics}
                finalSummaryElement={finalSummaryElement}
              />
            </Flex>
            {mp3.audioDeleted && (
              <Text fontSize="xs" color="gray.600" fontStyle="italic">
                No audio is available because one or more participants didn't
                consent to keep the audio
              </Text>
            )}
          </Flex>

          {/* Topics List (top section - fixed height, scrollable) */}
          <TopicList
            topics={topics.topics || []}
            useActiveTopic={useActiveTopic}
            autoscroll={false}
            transcriptId={transcriptId}
            status={transcript.data?.status || null}
            currentTranscriptText=""
            onTopicClick={handleTopicClick}
          />

          {/* Transcript with colored gutter (bottom section - scrollable container) */}
          {topics.topics && topics.topics.length > 0 && (
            <Box
              overflowY="auto"
              maxH="600px"
              pr={2}
              css={{
                "&::-webkit-scrollbar": {
                  width: "8px",
                },
                "&::-webkit-scrollbar-track": {
                  background: "transparent",
                },
                "&::-webkit-scrollbar-thumb": {
                  background: "#CBD5E0",
                  borderRadius: "4px",
                },
                "&::-webkit-scrollbar-thumb:hover": {
                  background: "#A0AEC0",
                },
              }}
            >
              <TranscriptWithGutter
                topics={topics.topics}
                getSpeakerName={getSpeakerName}
                onGutterClick={handleGutterClick}
              />
            </Box>
          )}

          {/* Final Summary (at bottom) */}
          {transcript.data && topics.topics ? (
            <FinalSummary
              transcript={transcript.data}
              topics={topics.topics}
              onUpdate={() => {
                transcript.refetch().then(() => {});
              }}
              finalSummaryRef={setFinalSummaryElement}
            />
          ) : (
            <Flex justify="center" alignItems="center" h="200px">
              <Flex direction="column" h="full" justify="center" align="center">
                {transcript?.data?.status == "processing" ? (
                  <Text>Loading Transcript</Text>
                ) : (
                  <Text>
                    There was an error generating the final summary, please come
                    back later
                  </Text>
                )}
              </Flex>
            </Flex>
          )}
        </Flex>
      </Grid>
    </>
  );
}
