import React, { useState } from "react";
import {
  Box,
  Table,
  Link,
  Flex,
  IconButton,
  Text,
  Spinner,
  Badge,
  VStack,
  Icon,
  Tooltip,
} from "@chakra-ui/react";
import { LuLink, LuRefreshCw } from "react-icons/lu";
import { FaStop } from "react-icons/fa";
import { FaCalendarAlt } from "react-icons/fa";
import type { components } from "../../../reflector-api";
import {
  useRoomActiveMeetings,
  useRoomUpcomingMeetings,
  useRoomIcsSync,
  useMeetingDeactivate,
} from "../../../lib/apiHooks";

type Room = components["schemas"]["Room"];
type Meeting = components["schemas"]["Meeting"];
type CalendarEventResponse = components["schemas"]["CalendarEventResponse"];
import { RoomActionsMenu } from "./RoomActionsMenu";
import { MEETING_DEFAULT_TIME_MINUTES } from "../../../[roomName]/[meetingId]/constants";
import { NonEmptyString, parseNonEmptyString } from "../../../lib/utils";

// Custom icon component that combines calendar and refresh icons
const CalendarSyncIcon = () => (
  <Box position="relative" display="inline-block" w="20px" h="20px">
    <Icon
      as={FaCalendarAlt}
      position="absolute"
      top={0}
      left={0}
      boxSize="20px"
    />
    <Box
      position="absolute"
      bottom="-2px"
      right="-2px"
      bg="white"
      borderRadius="full"
      p="1px"
      display="flex"
      alignItems="center"
      justifyContent="center"
      w="12px"
      h="12px"
    >
      <Icon as={LuRefreshCw} boxSize="10px" color="gray.700" />
    </Box>
  </Box>
);

interface RoomTableProps {
  rooms: Room[];
  linkCopied: string;
  onCopyUrl: (roomName: NonEmptyString) => void;
  onEdit: (roomId: string, roomData: any) => void;
  onDelete: (roomId: string) => void;
  loading?: boolean;
}

const getRoomModeDisplay = (mode: string): string => {
  switch (mode) {
    case "normal":
      return "2-4 people";
    case "group":
      return "2-200 people";
    default:
      return mode;
  }
};

const getRecordingDisplay = (type: string, trigger: string): string => {
  if (type === "none") return "-";
  if (type === "local") return "Local";
  if (type === "cloud") {
    switch (trigger) {
      case "none":
        return "Cloud (None)";
      case "prompt":
        return "Cloud (Prompt)";
      case "automatic-2nd-participant":
        return "Cloud (Auto)";
      default:
        return `Cloud (${trigger})`;
    }
  }
  return type;
};

const getZulipDisplay = (
  autoPost: boolean,
  stream: string,
  topic: string,
): string => {
  if (!autoPost) return "-";
  if (stream && topic) return `${stream} > ${topic}`;
  if (stream) return stream;
  return "Enabled";
};

function MeetingStatus({ roomName }: { roomName: string }) {
  const activeMeetingsQuery = useRoomActiveMeetings(roomName);
  const upcomingMeetingsQuery = useRoomUpcomingMeetings(roomName);
  const deactivateMutation = useMeetingDeactivate();

  const activeMeetings = activeMeetingsQuery.data || [];
  const upcomingMeetings = upcomingMeetingsQuery.data || [];

  if (activeMeetingsQuery.isLoading || upcomingMeetingsQuery.isLoading) {
    return <Spinner size="sm" />;
  }

  if (activeMeetings.length > 0) {
    const meeting = activeMeetings[0];
    const title = String(
      meeting.calendar_metadata?.["title"] || "Active Meeting",
    );
    return (
      <Flex alignItems="center" gap={2}>
        <VStack gap={1} alignItems="start">
          <Text fontSize="xs" color="gray.600" lineHeight={1}>
            {title}
          </Text>
          <Text fontSize="xs" color="gray.500" lineHeight={1}>
            {meeting.num_clients} participants
          </Text>
        </VStack>
        {activeMeetings.length === 1 && (meeting.num_clients ?? 0) < 2 && (
          <Tooltip.Root openDelay={100}>
            <Tooltip.Trigger asChild>
              <IconButton
                aria-label="End meeting"
                size="xs"
                variant="ghost"
                color="red.500"
                _hover={{ bg: "transparent", color: "red.600" }}
                onClick={() =>
                  deactivateMutation.mutate({
                    params: { path: { meeting_id: meeting.id } },
                  })
                }
                disabled={deactivateMutation.isPending}
              >
                {deactivateMutation.isPending ? (
                  <Spinner size="xs" />
                ) : (
                  <FaStop />
                )}
              </IconButton>
            </Tooltip.Trigger>
            <Tooltip.Positioner>
              <Tooltip.Content>
                End this meeting and stop any active recordings
              </Tooltip.Content>
            </Tooltip.Positioner>
          </Tooltip.Root>
        )}
      </Flex>
    );
  }

  if (upcomingMeetings.length > 0) {
    const event = upcomingMeetings[0];
    const startTime = new Date(event.start_time);
    const now = new Date();
    const diffMinutes = Math.floor(
      (startTime.getTime() - now.getTime()) / 60000,
    );

    return (
      <VStack gap={1} alignItems="start">
        <Badge colorScheme="orange" size="sm">
          {diffMinutes < MEETING_DEFAULT_TIME_MINUTES
            ? `In ${diffMinutes}m`
            : "Upcoming"}
        </Badge>
        <Text fontSize="xs" color="gray.600" lineHeight={1}>
          {event.title || "Scheduled Meeting"}
        </Text>
        <Text fontSize="xs" color="gray.500" lineHeight={1}>
          {startTime.toLocaleTimeString("en-US", {
            hour: "2-digit",
            minute: "2-digit",
            month: "short",
            day: "numeric",
          })}
        </Text>
      </VStack>
    );
  }

  return (
    <Text fontSize="xs" color="gray.500">
      No meetings
    </Text>
  );
}

export function RoomTable({
  rooms,
  linkCopied,
  onCopyUrl,
  onEdit,
  onDelete,
  loading,
}: RoomTableProps) {
  const [syncingRooms, setSyncingRooms] = useState<Set<NonEmptyString>>(
    new Set(),
  );
  const syncMutation = useRoomIcsSync();

  const handleForceSync = async (roomName: NonEmptyString) => {
    setSyncingRooms((prev) => new Set(prev).add(roomName));
    try {
      await syncMutation.mutateAsync({
        params: {
          path: { room_name: roomName },
        },
      });
    } catch (err) {
      console.error("Failed to sync calendar:", err);
    } finally {
      setSyncingRooms((prev) => {
        const next = new Set(prev);
        next.delete(roomName);
        return next;
      });
    }
  };

  return (
    <Box display={{ base: "none", lg: "block" }} position="relative">
      {loading && (
        <Flex
          position="absolute"
          top={0}
          left={0}
          right={0}
          bottom={0}
          align="center"
          justify="center"
        >
          <Spinner size="xl" color="gray.700" />
        </Flex>
      )}
      <Box
        opacity={loading ? 0.9 : 1}
        pointerEvents={loading ? "none" : "auto"}
        transition="opacity 0.2s ease-in-out"
      >
        <Table.Root>
          <Table.Header>
            <Table.Row>
              <Table.ColumnHeader width="250px" fontWeight="600">
                Room Name
              </Table.ColumnHeader>
              <Table.ColumnHeader width="200px" fontWeight="600">
                Current Meeting
              </Table.ColumnHeader>
              <Table.ColumnHeader width="200px" fontWeight="600">
                Zulip
              </Table.ColumnHeader>
              <Table.ColumnHeader width="120px" fontWeight="600">
                Room Size
              </Table.ColumnHeader>
              <Table.ColumnHeader width="150px" fontWeight="600">
                Recording
              </Table.ColumnHeader>
              <Table.ColumnHeader
                width="100px"
                fontWeight="600"
              ></Table.ColumnHeader>
            </Table.Row>
          </Table.Header>
          <Table.Body>
            {rooms.map((room) => (
              <Table.Row key={room.id}>
                <Table.Cell>
                  <Link href={`/${room.name}`}>{room.name}</Link>
                </Table.Cell>
                <Table.Cell>
                  <MeetingStatus roomName={room.name} />
                </Table.Cell>
                <Table.Cell>
                  {getZulipDisplay(
                    room.zulip_auto_post,
                    room.zulip_stream,
                    room.zulip_topic,
                  )}
                </Table.Cell>
                <Table.Cell>{getRoomModeDisplay(room.room_mode)}</Table.Cell>
                <Table.Cell>
                  {getRecordingDisplay(
                    room.recording_type,
                    room.recording_trigger,
                  )}
                </Table.Cell>
                <Table.Cell>
                  <Flex alignItems="center" gap={2} justifyContent="flex-end">
                    {room.ics_enabled && (
                      <IconButton
                        aria-label="Force sync calendar"
                        onClick={() =>
                          handleForceSync(
                            parseNonEmptyString(
                              room.name,
                              true,
                              "panic! room.name is required",
                            ),
                          )
                        }
                        size="sm"
                        variant="ghost"
                        disabled={syncingRooms.has(
                          parseNonEmptyString(
                            room.name,
                            true,
                            "panic! room.name is required",
                          ),
                        )}
                      >
                        {syncingRooms.has(
                          parseNonEmptyString(
                            room.name,
                            true,
                            "panic! room.name is required",
                          ),
                        ) ? (
                          <Spinner size="sm" />
                        ) : (
                          <CalendarSyncIcon />
                        )}
                      </IconButton>
                    )}
                    {linkCopied === room.name ? (
                      <Text color="green.500" fontSize="sm">
                        Copied!
                      </Text>
                    ) : (
                      <IconButton
                        aria-label="Copy URL"
                        onClick={() =>
                          onCopyUrl(
                            parseNonEmptyString(
                              room.name,
                              true,
                              "panic! room.name is required",
                            ),
                          )
                        }
                        size="sm"
                        variant="ghost"
                      >
                        <LuLink />
                      </IconButton>
                    )}
                    <RoomActionsMenu
                      roomId={room.id}
                      roomData={room}
                      onEdit={onEdit}
                      onDelete={onDelete}
                    />
                  </Flex>
                </Table.Cell>
              </Table.Row>
            ))}
          </Table.Body>
        </Table.Root>
      </Box>
    </Box>
  );
}
