"use client";

import {
  Button,
  Checkbox,
  CloseButton,
  Dialog,
  Field,
  Flex,
  Heading,
  Input,
  Select,
  Spinner,
  IconButton,
  createListCollection,
  useDisclosure,
  Tabs,
  Popover,
  Text,
  HStack,
} from "@chakra-ui/react";
import { useEffect, useMemo, useState } from "react";
import { LuEye, LuEyeOff, LuInfo } from "react-icons/lu";
import useRoomList from "./useRoomList";
import type { components } from "../../reflector-api";
import {
  useRoomCreate,
  useRoomUpdate,
  useRoomDelete,
  useZulipStreams,
  useZulipTopics,
  useRoomGet,
  useRoomTestWebhook,
  useConfig,
} from "../../lib/apiHooks";
import { RoomList } from "./_components/RoomList";
import { PaginationPage } from "../browse/_components/Pagination";
import {
  assertExists,
  NonEmptyString,
  parseNonEmptyString,
} from "../../lib/utils";
import ICSSettings from "./_components/ICSSettings";
import { roomAbsoluteUrl } from "../../lib/routesClient";

type Room = components["schemas"]["Room"];

interface SelectOption {
  label: string;
  value: string;
}

const RESERVED_PATHS = ["browse", "rooms", "transcripts"];
const SUCCESS_EMOJI = "✅";
const ERROR_EMOJI = "❌";

const roomModeOptions: SelectOption[] = [
  { label: "2-4 people", value: "normal" },
  { label: "2-200 people", value: "group" },
];

const recordingTriggerOptions: SelectOption[] = [
  { label: "None", value: "none" },
  { label: "Prompt", value: "prompt" },
  { label: "Automatic", value: "automatic-2nd-participant" },
];

const recordingTypeOptions: SelectOption[] = [
  { label: "None", value: "none" },
  { label: "Local", value: "local" },
  { label: "Cloud", value: "cloud" },
];

const platformOptions: SelectOption[] = [
  { label: "Whereby", value: "whereby" },
  { label: "Daily", value: "daily" },
  { label: "LiveKit", value: "livekit" },
];

const roomInitialState = {
  name: "",
  zulipAutoPost: false,
  zulipStream: "",
  zulipTopic: "",
  isLocked: false,
  roomMode: "normal",
  recordingType: "cloud",
  recordingTrigger: "automatic-2nd-participant",
  isShared: false,
  webhookUrl: "",
  webhookSecret: "",
  icsUrl: "",
  icsEnabled: false,
  icsFetchInterval: 5,
  platform: "whereby",
  skipConsent: false,
  emailTranscriptTo: "",
  storeVideo: false,
};

export default function RoomsList() {
  const { open, onOpen, onClose } = useDisclosure();

  // Create collections for Select components
  const roomModeCollection = createListCollection({
    items: roomModeOptions,
  });

  const recordingTriggerCollection = createListCollection({
    items: recordingTriggerOptions,
  });

  const recordingTypeCollection = createListCollection({
    items: recordingTypeOptions,
  });

  const platformCollection = createListCollection({
    items: platformOptions,
  });

  const [roomInput, setRoomInput] = useState<null | typeof roomInitialState>(
    null,
  );
  const [isEditing, setIsEditing] = useState(false);
  const [editRoomId, setEditRoomId] = useState<string | null>(null);
  const {
    loading,
    response,
    refetch,
    error: roomListError,
  } = useRoomList(PaginationPage(1));
  const [nameError, setNameError] = useState("");
  const [linkCopied, setLinkCopied] = useState("");
  const [selectedStreamId, setSelectedStreamId] = useState<number | null>(null);
  const [testingWebhook, setTestingWebhook] = useState(false);
  const [webhookTestResult, setWebhookTestResult] = useState<string | null>(
    null,
  );
  const [showWebhookSecret, setShowWebhookSecret] = useState(false);
  const [emailTranscriptEnabled, setEmailTranscriptEnabled] = useState(false);

  const createRoomMutation = useRoomCreate();
  const updateRoomMutation = useRoomUpdate();
  const deleteRoomMutation = useRoomDelete();
  const { data: config } = useConfig();
  const zulipEnabled = config?.zulip_enabled ?? false;
  const emailEnabled = config?.email_enabled ?? false;
  const { data: streams = [] } = useZulipStreams(zulipEnabled);
  const { data: topics = [] } = useZulipTopics(selectedStreamId);

  const {
    data: detailedEditedRoom,
    isLoading: isDetailedEditedRoomLoading,
    error: detailedEditedRoomError,
  } = useRoomGet(editRoomId);

  const error = roomListError || detailedEditedRoomError;

  // room being edited, as fetched from the server
  const editedRoom: typeof roomInitialState | null = useMemo(
    () =>
      detailedEditedRoom
        ? {
            name: detailedEditedRoom.name,
            zulipAutoPost: detailedEditedRoom.zulip_auto_post,
            zulipStream: detailedEditedRoom.zulip_stream,
            zulipTopic: detailedEditedRoom.zulip_topic,
            isLocked: detailedEditedRoom.is_locked,
            roomMode:
              detailedEditedRoom.platform === "daily"
                ? "group"
                : detailedEditedRoom.room_mode,
            recordingType: detailedEditedRoom.recording_type,
            recordingTrigger:
              detailedEditedRoom.platform === "daily"
                ? detailedEditedRoom.recording_type === "cloud"
                  ? "automatic-2nd-participant"
                  : "none"
                : detailedEditedRoom.recording_trigger,
            isShared: detailedEditedRoom.is_shared,
            webhookUrl: detailedEditedRoom.webhook_url || "",
            webhookSecret: detailedEditedRoom.webhook_secret || "",
            icsUrl: detailedEditedRoom.ics_url || "",
            icsEnabled: detailedEditedRoom.ics_enabled || false,
            icsFetchInterval: detailedEditedRoom.ics_fetch_interval || 5,
            platform: detailedEditedRoom.platform,
            skipConsent: detailedEditedRoom.skip_consent || false,
            emailTranscriptTo: detailedEditedRoom.email_transcript_to || "",
            storeVideo: detailedEditedRoom.store_video || false,
          }
        : null,
    [detailedEditedRoom],
  );

  // a room input value or a last api room state
  const room = roomInput || editedRoom || roomInitialState;

  const roomTestWebhookMutation = useRoomTestWebhook();

  // Update selected stream ID when zulip stream changes
  useEffect(() => {
    if (room.zulipStream && streams.length > 0) {
      const selectedStream = streams.find((s) => s.name === room.zulipStream);
      if (selectedStream !== undefined) {
        setSelectedStreamId(selectedStream.stream_id);
      }
    } else {
      setSelectedStreamId(null);
    }
  }, [room.zulipStream, streams]);

  const streamOptions: SelectOption[] = streams.map((stream) => {
    return { label: stream.name, value: stream.name };
  });

  const topicOptions: SelectOption[] = topics.map((topic) => ({
    label: topic.name,
    value: topic.name,
  }));

  const streamCollection = createListCollection({
    items: streamOptions,
  });

  const topicCollection = createListCollection({
    items: topicOptions,
  });

  const handleCopyUrl = (roomName: NonEmptyString) => {
    navigator.clipboard.writeText(roomAbsoluteUrl(roomName)).then(() => {
      setLinkCopied(roomName);
      setTimeout(() => {
        setLinkCopied("");
      }, 2000);
    });
  };

  const handleCloseDialog = () => {
    setShowWebhookSecret(false);
    setWebhookTestResult(null);
    setEditRoomId(null);
    onClose();
  };

  const handleTestWebhook = async () => {
    if (!room.webhookUrl) {
      setWebhookTestResult("Please enter a webhook URL first");
      return;
    }
    if (!editRoomId) {
      console.error("No room ID to test webhook");
      return;
    }

    setTestingWebhook(true);
    setWebhookTestResult(null);

    try {
      const response = await roomTestWebhookMutation.mutateAsync({
        params: {
          path: {
            room_id: editRoomId,
          },
        },
      });

      if (response.success) {
        setWebhookTestResult(
          `${SUCCESS_EMOJI} Webhook test successful! Status: ${response.status_code}`,
        );
      } else {
        let errorMsg = `${ERROR_EMOJI} Webhook test failed`;
        errorMsg += ` (Status: ${response.status_code})`;
        if (response.error) {
          errorMsg += `: ${response.error}`;
        } else if (response.response_preview) {
          // Try to parse and extract meaningful error from response
          // Specific to N8N at the moment, as there is no specification for that
          // We could just display as is, but decided here to dig a little bit more.
          try {
            const preview = JSON.parse(response.response_preview);
            if (preview.message) {
              errorMsg += `: ${preview.message}`;
            }
          } catch {
            // If not JSON, just show the preview text (truncated)
            const previewText = response.response_preview.substring(0, 150);
            errorMsg += `: ${previewText}`;
          }
        } else if (response?.message) {
          errorMsg += `: ${response.message}`;
        }
        setWebhookTestResult(errorMsg);
      }
    } catch (error) {
      console.error("Error testing webhook:", error);
      setWebhookTestResult("❌ Failed to test webhook. Please check your URL.");
    } finally {
      setTestingWebhook(false);
    }

    // Clear result after 5 seconds
    setTimeout(() => {
      setWebhookTestResult(null);
    }, 5000);
  };

  const handleSaveRoom = async () => {
    try {
      if (RESERVED_PATHS.includes(room.name)) {
        setNameError("This room name is reserved. Please choose another name.");
        return;
      }

      const platform = room.platform as "whereby" | "daily" | "livekit";

      const roomData = {
        name: room.name,
        zulip_auto_post: room.zulipAutoPost,
        zulip_stream: room.zulipStream,
        zulip_topic: room.zulipTopic,
        is_locked: room.isLocked,
        room_mode: platform === "daily" ? "group" : room.roomMode,
        recording_type: room.recordingType,
        recording_trigger:
          platform === "daily"
            ? room.recordingType === "cloud"
              ? "automatic-2nd-participant"
              : "none"
            : room.recordingTrigger,
        is_shared: room.isShared,
        webhook_url: room.webhookUrl,
        webhook_secret: room.webhookSecret,
        ics_url: room.icsUrl,
        ics_enabled: room.icsEnabled,
        ics_fetch_interval: room.icsFetchInterval,
        platform,
        skip_consent: room.skipConsent,
        email_transcript_to: room.emailTranscriptTo || null,
        store_video: room.storeVideo,
      };

      if (isEditing) {
        await updateRoomMutation.mutateAsync({
          params: {
            path: { room_id: assertExists(editRoomId) },
          },
          body: roomData,
        });
      } else {
        await createRoomMutation.mutateAsync({
          body: roomData,
        });
      }

      setRoomInput(null);
      setIsEditing(false);
      setEditRoomId(null);
      setNameError("");
      refetch();
      onClose();
      handleCloseDialog();
    } catch (err: any) {
      if (
        err?.status === 400 &&
        err?.body?.detail == "Room name is not unique"
      ) {
        setNameError(
          "This room name is already taken. Please choose a different name.",
        );
      } else {
        setNameError("An error occurred. Please try again.");
      }
    }
  };

  const handleEditRoom = async (roomId: string, roomData) => {
    // Reset states
    setShowWebhookSecret(false);
    setWebhookTestResult(null);
    setEmailTranscriptEnabled(!!roomData.email_transcript_to);

    setRoomInput({
      name: roomData.name,
      zulipAutoPost: roomData.zulip_auto_post,
      zulipStream: roomData.zulip_stream,
      zulipTopic: roomData.zulip_topic,
      isLocked: roomData.is_locked,
      roomMode: roomData.platform === "daily" ? "group" : roomData.room_mode, // Daily always uses 2-200
      recordingType: roomData.recording_type,
      recordingTrigger:
        roomData.platform === "daily"
          ? roomData.recording_type === "cloud"
            ? "automatic-2nd-participant"
            : "none"
          : roomData.recording_trigger,
      isShared: roomData.is_shared,
      webhookUrl: roomData.webhook_url || "",
      webhookSecret: roomData.webhook_secret || "",
      icsUrl: roomData.ics_url || "",
      icsEnabled: roomData.ics_enabled || false,
      icsFetchInterval: roomData.ics_fetch_interval || 5,
      platform: roomData.platform,
      skipConsent: roomData.skip_consent || false,
      emailTranscriptTo: roomData.email_transcript_to || "",
      storeVideo: roomData.store_video || false,
    });
    setEditRoomId(roomId);
    setIsEditing(true);
    setNameError("");
    onOpen();
  };

  const handleDeleteRoom = async (roomId: string) => {
    try {
      await deleteRoomMutation.mutateAsync({
        params: {
          path: { room_id: roomId },
        },
      });
      refetch();
    } catch (err) {
      console.error(err);
    }
  };

  const handleRoomChange = (e) => {
    let { name, value, type, checked } = e.target;
    if (name === "name") {
      value = value
        .replace(/[^a-zA-Z0-9\s-]/g, "")
        .replace(/\s+/g, "-")
        .toLowerCase();
      setNameError("");
    }
    setRoomInput({
      ...room,
      [name]: type === "checkbox" ? checked : value,
    });
  };

  const myRooms: Room[] =
    response?.items.filter((roomData) => !roomData.is_shared) || [];
  const sharedRooms: Room[] =
    response?.items.filter((roomData) => roomData.is_shared) || [];

  if (loading && !response)
    return (
      <Flex
        flexDir="column"
        alignItems="center"
        justifyContent="center"
        h="100%"
      >
        <Spinner size="xl" />
      </Flex>
    );

  if (roomListError)
    return <div>{`${roomListError.name}: ${roomListError.message}`}</div>;

  return (
    <Flex
      flexDir="column"
      w={{ base: "full", md: "container.xl" }}
      mx="auto"
      pt={2}
    >
      <Flex
        flexDir="row"
        justifyContent="space-between"
        alignItems="center"
        mb={4}
      >
        <Heading size="lg">Rooms {loading && <Spinner size="sm" />}</Heading>
        <Button
          colorPalette="primary"
          onClick={() => {
            setIsEditing(false);
            setRoomInput(null);
            setNameError("");
            setShowWebhookSecret(false);
            setWebhookTestResult(null);
            setEmailTranscriptEnabled(false);
            onOpen();
          }}
        >
          Add Room
        </Button>
      </Flex>

      <Dialog.Root
        open={open}
        onOpenChange={(e) => (e.open ? onOpen() : handleCloseDialog())}
        size="lg"
      >
        <Dialog.Backdrop />
        <Dialog.Positioner>
          <Dialog.Content>
            <Dialog.Header>
              <Dialog.Title>
                {isEditing ? "Edit Room" : "Add Room"}
              </Dialog.Title>
              <Dialog.CloseTrigger asChild>
                <CloseButton />
              </Dialog.CloseTrigger>
            </Dialog.Header>
            <Dialog.Body>
              <form
                id="room-form"
                onSubmit={(e) => {
                  e.preventDefault();
                  handleSaveRoom();
                }}
              >
                <Tabs.Root defaultValue="general">
                  <Tabs.List>
                    <Tabs.Trigger value="general">General</Tabs.Trigger>
                    <Tabs.Trigger value="calendar">Calendar</Tabs.Trigger>
                    {(zulipEnabled || emailEnabled) && (
                      <Tabs.Trigger value="share">Share</Tabs.Trigger>
                    )}
                    <Tabs.Trigger value="webhook">WebHook</Tabs.Trigger>
                  </Tabs.List>

                  <Tabs.Content value="general" pt={6}>
                    <Field.Root>
                      <Field.Label>Room name</Field.Label>
                      <Input
                        name="name"
                        placeholder="room-name"
                        value={room.name}
                        onChange={handleRoomChange}
                        enterKeyHint="next"
                      />
                      <Field.HelperText>
                        No spaces or special characters allowed
                      </Field.HelperText>
                      {nameError && (
                        <Field.ErrorText>{nameError}</Field.ErrorText>
                      )}
                    </Field.Root>

                    <Field.Root mt={4}>
                      <Field.Label>Platform</Field.Label>
                      <Select.Root
                        value={[room.platform]}
                        onValueChange={(e) => {
                          const newPlatform = e.value[0] as
                            | "whereby"
                            | "daily"
                            | "livekit";
                          const updates: Partial<typeof room> = {
                            platform: newPlatform,
                          };
                          if (newPlatform === "daily") {
                            updates.roomMode = "group";
                            updates.recordingTrigger =
                              room.recordingType === "cloud"
                                ? "automatic-2nd-participant"
                                : "none";
                          } else {
                            if (room.recordingType !== "cloud") {
                              updates.recordingTrigger = "none";
                            }
                          }
                          setRoomInput({ ...room, ...updates });
                        }}
                        collection={platformCollection}
                      >
                        <Select.HiddenSelect />
                        <Select.Control>
                          <Select.Trigger>
                            <Select.ValueText placeholder="Select platform" />
                          </Select.Trigger>
                          <Select.IndicatorGroup>
                            <Select.Indicator />
                          </Select.IndicatorGroup>
                        </Select.Control>
                        <Select.Positioner>
                          <Select.Content>
                            {platformOptions.map((option) => (
                              <Select.Item key={option.value} item={option}>
                                {option.label}
                                <Select.ItemIndicator />
                              </Select.Item>
                            ))}
                          </Select.Content>
                        </Select.Positioner>
                      </Select.Root>
                    </Field.Root>

                    <Field.Root mt={4}>
                      <Checkbox.Root
                        name="isLocked"
                        checked={room.isLocked}
                        onCheckedChange={(e) => {
                          const syntheticEvent = {
                            target: {
                              name: "isLocked",
                              type: "checkbox",
                              checked: e.checked,
                            },
                          };
                          handleRoomChange(syntheticEvent);
                        }}
                      >
                        <Checkbox.HiddenInput />
                        <Checkbox.Control>
                          <Checkbox.Indicator />
                        </Checkbox.Control>
                        <Checkbox.Label>Locked room</Checkbox.Label>
                      </Checkbox.Root>
                    </Field.Root>
                    {room.platform !== "daily" && (
                      <Field.Root mt={4}>
                        <Field.Label>Room size</Field.Label>
                        <Select.Root
                          value={[room.roomMode]}
                          onValueChange={(e) =>
                            setRoomInput({ ...room, roomMode: e.value[0] })
                          }
                          collection={roomModeCollection}
                        >
                          <Select.HiddenSelect />
                          <Select.Control>
                            <Select.Trigger>
                              <Select.ValueText placeholder="Select room size" />
                            </Select.Trigger>
                            <Select.IndicatorGroup>
                              <Select.Indicator />
                            </Select.IndicatorGroup>
                          </Select.Control>
                          <Select.Positioner>
                            <Select.Content>
                              {roomModeOptions.map((option) => (
                                <Select.Item key={option.value} item={option}>
                                  {option.label}
                                  <Select.ItemIndicator />
                                </Select.Item>
                              ))}
                            </Select.Content>
                          </Select.Positioner>
                        </Select.Root>
                      </Field.Root>
                    )}
                    <Field.Root mt={4}>
                      <HStack gap={2} alignItems="center">
                        <Field.Label>Recording type</Field.Label>
                        <Popover.Root>
                          <Popover.Trigger asChild>
                            <IconButton
                              aria-label="Recording type help"
                              variant="ghost"
                              size="xs"
                              colorPalette="gray"
                            >
                              <LuInfo />
                            </IconButton>
                          </Popover.Trigger>
                          <Popover.Positioner>
                            <Popover.Content>
                              <Popover.Arrow />
                              <Popover.Body>
                                <Text fontSize="sm" lineHeight="1.6">
                                  <strong>None:</strong> No recording will be
                                  created.
                                  <br />
                                  <br />
                                  <strong>Local:</strong> Recording happens on
                                  each participant's device. Files are saved
                                  locally.
                                  <br />
                                  <br />
                                  <strong>Cloud:</strong> Recording happens on
                                  the platform's servers and is available after
                                  the meeting ends.
                                </Text>
                              </Popover.Body>
                            </Popover.Content>
                          </Popover.Positioner>
                        </Popover.Root>
                      </HStack>
                      <Select.Root
                        value={[room.recordingType]}
                        onValueChange={(e) => {
                          const newRecordingType = e.value[0];
                          const updates: Partial<typeof room> = {
                            recordingType: newRecordingType,
                          };
                          if (room.platform === "daily") {
                            updates.recordingTrigger =
                              newRecordingType === "cloud"
                                ? "automatic-2nd-participant"
                                : "none";
                          } else {
                            updates.recordingTrigger =
                              newRecordingType !== "cloud"
                                ? "none"
                                : room.recordingTrigger;
                          }
                          setRoomInput({ ...room, ...updates });
                        }}
                        collection={recordingTypeCollection}
                      >
                        <Select.HiddenSelect />
                        <Select.Control>
                          <Select.Trigger>
                            <Select.ValueText placeholder="Select recording type" />
                          </Select.Trigger>
                          <Select.IndicatorGroup>
                            <Select.Indicator />
                          </Select.IndicatorGroup>
                        </Select.Control>
                        <Select.Positioner>
                          <Select.Content>
                            {recordingTypeOptions.map((option) => (
                              <Select.Item key={option.value} item={option}>
                                {option.label}
                                <Select.ItemIndicator />
                              </Select.Item>
                            ))}
                          </Select.Content>
                        </Select.Positioner>
                      </Select.Root>
                    </Field.Root>
                    {room.recordingType === "cloud" &&
                      room.platform !== "daily" && (
                        <Field.Root mt={4}>
                          <HStack gap={2} alignItems="center">
                            <Field.Label>Recording start trigger</Field.Label>
                            <Popover.Root>
                              <Popover.Trigger asChild>
                                <IconButton
                                  aria-label="Recording start trigger help"
                                  variant="ghost"
                                  size="xs"
                                  colorPalette="gray"
                                >
                                  <LuInfo />
                                </IconButton>
                              </Popover.Trigger>
                              <Popover.Positioner>
                                <Popover.Content>
                                  <Popover.Arrow />
                                  <Popover.Body>
                                    <Text fontSize="sm" lineHeight="1.6">
                                      <strong>None:</strong> Recording must be
                                      started manually by a participant.
                                      <br />
                                      <br />
                                      <strong>Prompt:</strong> Participants will
                                      be prompted to start recording when they
                                      join.
                                      <br />
                                      <br />
                                      <strong>Automatic:</strong> Recording
                                      starts automatically when a second
                                      participant joins.
                                    </Text>
                                  </Popover.Body>
                                </Popover.Content>
                              </Popover.Positioner>
                            </Popover.Root>
                          </HStack>
                          <Select.Root
                            value={[room.recordingTrigger]}
                            onValueChange={(e) =>
                              setRoomInput({
                                ...room,
                                recordingTrigger: e.value[0],
                              })
                            }
                            collection={recordingTriggerCollection}
                          >
                            <Select.HiddenSelect />
                            <Select.Control>
                              <Select.Trigger>
                                <Select.ValueText placeholder="Select trigger" />
                              </Select.Trigger>
                              <Select.IndicatorGroup>
                                <Select.Indicator />
                              </Select.IndicatorGroup>
                            </Select.Control>
                            <Select.Positioner>
                              <Select.Content>
                                {recordingTriggerOptions.map((option) => (
                                  <Select.Item key={option.value} item={option}>
                                    {option.label}
                                    <Select.ItemIndicator />
                                  </Select.Item>
                                ))}
                              </Select.Content>
                            </Select.Positioner>
                          </Select.Root>
                        </Field.Root>
                      )}

                    <Field.Root mt={4}>
                      <Checkbox.Root
                        name="isShared"
                        checked={room.isShared}
                        onCheckedChange={(e) => {
                          const syntheticEvent = {
                            target: {
                              name: "isShared",
                              type: "checkbox",
                              checked: e.checked,
                            },
                          };
                          handleRoomChange(syntheticEvent);
                        }}
                      >
                        <Checkbox.HiddenInput />
                        <Checkbox.Control>
                          <Checkbox.Indicator />
                        </Checkbox.Control>
                        <Checkbox.Label>Shared room</Checkbox.Label>
                      </Checkbox.Root>
                    </Field.Root>
                    {room.recordingType === "cloud" && (
                      <Field.Root mt={4}>
                        <Checkbox.Root
                          name="skipConsent"
                          checked={room.skipConsent}
                          onCheckedChange={(e) => {
                            const syntheticEvent = {
                              target: {
                                name: "skipConsent",
                                type: "checkbox",
                                checked: e.checked,
                              },
                            };
                            handleRoomChange(syntheticEvent);
                          }}
                        >
                          <Checkbox.HiddenInput />
                          <Checkbox.Control>
                            <Checkbox.Indicator />
                          </Checkbox.Control>
                          <Checkbox.Label>Skip consent dialog</Checkbox.Label>
                        </Checkbox.Root>
                        <Field.HelperText>
                          When enabled, participants won't be asked for
                          recording consent. Audio will be stored automatically.
                        </Field.HelperText>
                      </Field.Root>
                    )}
                    {room.platform === "daily" &&
                      room.recordingType === "cloud" && (
                        <Field.Root mt={4}>
                          <Checkbox.Root
                            name="storeVideo"
                            checked={room.storeVideo}
                            onCheckedChange={(e) => {
                              const syntheticEvent = {
                                target: {
                                  name: "storeVideo",
                                  type: "checkbox",
                                  checked: e.checked,
                                },
                              };
                              handleRoomChange(syntheticEvent);
                            }}
                          >
                            <Checkbox.HiddenInput />
                            <Checkbox.Control>
                              <Checkbox.Indicator />
                            </Checkbox.Control>
                            <Checkbox.Label>
                              Store video recording
                            </Checkbox.Label>
                          </Checkbox.Root>
                          <Field.HelperText>
                            When enabled, a composed video recording will be
                            saved alongside audio. Disabling saves significant
                            storage.
                          </Field.HelperText>
                        </Field.Root>
                      )}
                  </Tabs.Content>

                  <Tabs.Content value="share" pt={6}>
                    {emailEnabled && (
                      <>
                        <Field.Root>
                          <Checkbox.Root
                            checked={emailTranscriptEnabled}
                            onCheckedChange={(e) => {
                              setEmailTranscriptEnabled(!!e.checked);
                              if (!e.checked) {
                                setRoomInput({
                                  ...room,
                                  emailTranscriptTo: "",
                                });
                              }
                            }}
                          >
                            <Checkbox.HiddenInput />
                            <Checkbox.Control>
                              <Checkbox.Indicator />
                            </Checkbox.Control>
                            <Checkbox.Label>
                              Email me transcript when processed
                            </Checkbox.Label>
                          </Checkbox.Root>
                        </Field.Root>
                        {emailTranscriptEnabled && (
                          <Field.Root mt={2}>
                            <Input
                              name="emailTranscriptTo"
                              type="email"
                              placeholder="your@email.com"
                              value={room.emailTranscriptTo}
                              onChange={handleRoomChange}
                            />
                            <Field.HelperText>
                              Transcript will be emailed to this address after
                              processing
                            </Field.HelperText>
                          </Field.Root>
                        )}
                      </>
                    )}
                    {zulipEnabled && (
                      <>
                        <Field.Root mt={emailEnabled ? 4 : 0}>
                          <Checkbox.Root
                            name="zulipAutoPost"
                            checked={room.zulipAutoPost}
                            onCheckedChange={(e) => {
                              const syntheticEvent = {
                                target: {
                                  name: "zulipAutoPost",
                                  type: "checkbox",
                                  checked: e.checked,
                                },
                              };
                              handleRoomChange(syntheticEvent);
                            }}
                          >
                            <Checkbox.HiddenInput />
                            <Checkbox.Control>
                              <Checkbox.Indicator />
                            </Checkbox.Control>
                            <Checkbox.Label>
                              Automatically post transcription to Zulip
                            </Checkbox.Label>
                          </Checkbox.Root>
                        </Field.Root>
                        <Field.Root mt={4}>
                          <Field.Label>Zulip stream</Field.Label>
                          <Select.Root
                            value={room.zulipStream ? [room.zulipStream] : []}
                            onValueChange={(e) =>
                              setRoomInput({
                                ...room,
                                zulipStream: e.value[0],
                                zulipTopic: "",
                              })
                            }
                            collection={streamCollection}
                            disabled={!room.zulipAutoPost}
                          >
                            <Select.HiddenSelect />
                            <Select.Control>
                              <Select.Trigger>
                                <Select.ValueText placeholder="Select stream" />
                              </Select.Trigger>
                              <Select.IndicatorGroup>
                                <Select.Indicator />
                              </Select.IndicatorGroup>
                            </Select.Control>
                            <Select.Positioner>
                              <Select.Content>
                                {streamOptions.map((option) => (
                                  <Select.Item key={option.value} item={option}>
                                    {option.label}
                                    <Select.ItemIndicator />
                                  </Select.Item>
                                ))}
                              </Select.Content>
                            </Select.Positioner>
                          </Select.Root>
                        </Field.Root>
                        <Field.Root mt={4}>
                          <Field.Label>Zulip topic</Field.Label>
                          <Select.Root
                            value={room.zulipTopic ? [room.zulipTopic] : []}
                            onValueChange={(e) =>
                              setRoomInput({
                                ...room,
                                zulipTopic: e.value[0],
                              })
                            }
                            collection={topicCollection}
                            disabled={!room.zulipAutoPost}
                          >
                            <Select.HiddenSelect />
                            <Select.Control>
                              <Select.Trigger>
                                <Select.ValueText placeholder="Select topic" />
                              </Select.Trigger>
                              <Select.IndicatorGroup>
                                <Select.Indicator />
                              </Select.IndicatorGroup>
                            </Select.Control>
                            <Select.Positioner>
                              <Select.Content>
                                {topicOptions.map((option) => (
                                  <Select.Item key={option.value} item={option}>
                                    {option.label}
                                    <Select.ItemIndicator />
                                  </Select.Item>
                                ))}
                              </Select.Content>
                            </Select.Positioner>
                          </Select.Root>
                        </Field.Root>
                      </>
                    )}
                  </Tabs.Content>

                  <Tabs.Content value="webhook" pt={6}>
                    <Field.Root>
                      <Field.Label>Webhook URL</Field.Label>
                      <Input
                        name="webhookUrl"
                        placeholder="https://example.com/webhook"
                        value={room.webhookUrl}
                        onChange={handleRoomChange}
                        enterKeyHint="next"
                      />
                      <Field.HelperText>
                        Optional: URL to receive notifications when transcripts
                        are ready
                      </Field.HelperText>
                    </Field.Root>

                    {room.webhookUrl && (
                      <>
                        <Field.Root mt={4}>
                          <Field.Label>Webhook Secret</Field.Label>
                          <Flex gap={2}>
                            <Input
                              name="webhookSecret"
                              type={showWebhookSecret ? "text" : "password"}
                              value={room.webhookSecret}
                              onChange={handleRoomChange}
                              placeholder={
                                isEditing && room.webhookSecret
                                  ? "••••••••"
                                  : "Leave empty to auto-generate"
                              }
                              flex="1"
                            />
                            {isEditing && room.webhookSecret && (
                              <IconButton
                                size="sm"
                                variant="ghost"
                                aria-label={
                                  showWebhookSecret
                                    ? "Hide secret"
                                    : "Show secret"
                                }
                                onClick={() =>
                                  setShowWebhookSecret(!showWebhookSecret)
                                }
                              >
                                {showWebhookSecret ? <LuEyeOff /> : <LuEye />}
                              </IconButton>
                            )}
                          </Flex>
                          <Field.HelperText>
                            Used for HMAC signature verification (auto-generated
                            if left empty)
                          </Field.HelperText>
                        </Field.Root>

                        {isEditing && (
                          <>
                            <Flex
                              mt={2}
                              gap={2}
                              alignItems="flex-start"
                              direction="column"
                            >
                              <Button
                                size="sm"
                                variant="outline"
                                onClick={handleTestWebhook}
                                disabled={testingWebhook || !room.webhookUrl}
                              >
                                {testingWebhook ? (
                                  <>
                                    <Spinner size="xs" mr={2} />
                                    Testing...
                                  </>
                                ) : (
                                  "Test Webhook"
                                )}
                              </Button>
                              {webhookTestResult && (
                                <div
                                  style={{
                                    fontSize: "14px",
                                    wordBreak: "break-word",
                                    maxWidth: "100%",
                                    padding: "8px",
                                    borderRadius: "4px",
                                    backgroundColor:
                                      webhookTestResult.startsWith(
                                        SUCCESS_EMOJI,
                                      )
                                        ? "#f0fdf4"
                                        : "#fef2f2",
                                    border: `1px solid ${webhookTestResult.startsWith(SUCCESS_EMOJI) ? "#86efac" : "#fca5a5"}`,
                                  }}
                                >
                                  {webhookTestResult}
                                </div>
                              )}
                            </Flex>
                          </>
                        )}
                      </>
                    )}
                  </Tabs.Content>

                  <Tabs.Content value="calendar" pt={6}>
                    <Field.Root>
                      <ICSSettings
                        roomName={
                          room.name
                            ? parseNonEmptyString(
                                room.name,
                                true,
                                "panic! room.name required",
                              )
                            : null
                        }
                        icsUrl={room.icsUrl}
                        icsEnabled={room.icsEnabled}
                        icsFetchInterval={room.icsFetchInterval}
                        onChange={(settings) => {
                          setRoomInput({
                            ...room,
                            icsUrl:
                              settings.ics_url !== undefined
                                ? settings.ics_url
                                : room.icsUrl,
                            icsEnabled:
                              settings.ics_enabled !== undefined
                                ? settings.ics_enabled
                                : room.icsEnabled,
                            icsFetchInterval:
                              settings.ics_fetch_interval !== undefined
                                ? settings.ics_fetch_interval
                                : room.icsFetchInterval,
                          });
                        }}
                        isOwner={true}
                        isEditing={isEditing}
                      />
                    </Field.Root>
                  </Tabs.Content>
                </Tabs.Root>
              </form>
            </Dialog.Body>
            <Dialog.Footer>
              <Button variant="ghost" onClick={handleCloseDialog}>
                Cancel
              </Button>
              <Button
                type="submit"
                colorPalette="primary"
                form="room-form"
                disabled={
                  !room.name || (room.zulipAutoPost && !room.zulipTopic)
                }
              >
                {isEditing ? "Save" : "Add"}
              </Button>
            </Dialog.Footer>
          </Dialog.Content>
        </Dialog.Positioner>
      </Dialog.Root>

      <RoomList
        title="My Rooms"
        rooms={myRooms}
        linkCopied={linkCopied}
        onCopyUrl={handleCopyUrl}
        onEdit={handleEditRoom}
        onDelete={handleDeleteRoom}
        emptyMessage="No rooms found"
      />

      <RoomList
        title="Shared Rooms"
        rooms={sharedRooms}
        linkCopied={linkCopied}
        onCopyUrl={handleCopyUrl}
        onEdit={handleEditRoom}
        onDelete={handleDeleteRoom}
        emptyMessage="No shared rooms found"
        pt={4}
      />
    </Flex>
  );
}
