import React, { useMemo, useState } from 'react';
import { useAtomValue } from 'jotai';
import { Avatar, Box, config, Icon, IconButton, Icons, IconSrc, MenuItem, Text } from 'folds';
import { JoinRule } from 'matrix-js-sdk';
import { PageNav, PageNavContent, PageNavHeader, PageRoot } from '../../components/page';
import { ScreenSize, useScreenSizeContext } from '../../hooks/useScreenSize';
import { useMatrixClient } from '../../hooks/useMatrixClient';
import { mxcUrlToHttp } from '../../utils/matrix';
import { useMediaAuthentication } from '../../hooks/useMediaAuthentication';
import { useRoomAvatar, useRoomJoinRule, useRoomName } from '../../hooks/useRoomMeta';
import { mDirectAtom } from '../../state/mDirectList';
import { RoomAvatar, RoomIcon } from '../../components/room-avatar';
import { General } from './general';
import { Members } from '../common-settings/members';
import { EmojisStickers } from '../common-settings/emojis-stickers';
import { Soundboard } from '../common-settings/soundboard';
import { Permissions } from './permissions';
import { RoomSettingsPage } from '../../state/roomSettings';
import { useRoom } from '../../hooks/useRoom';
import { DeveloperTools } from '../common-settings/developer-tools';
import { ExportRoomHistory } from './ExportRoomHistory';
import { RoomActivityLog } from './RoomActivityLog';
import { RoomServerACL } from './RoomServerACL';
import { RoomInsights } from './RoomInsights';
import { PolicyListViewer } from './PolicyListViewer';
import { usePowerLevels, readPowerLevel } from '../../hooks/usePowerLevels';
import { useRoomCreators } from '../../hooks/useRoomCreators';
import { StateEvent } from '../../../types/matrix/room';

type RoomSettingsMenuItem = {
  page: RoomSettingsPage;
  name: string;
  icon: IconSrc;
};

const BASE_MENU_ITEMS: RoomSettingsMenuItem[] = [
  {
    page: RoomSettingsPage.GeneralPage,
    name: 'General',
    icon: Icons.Setting,
  },
  {
    page: RoomSettingsPage.MembersPage,
    name: 'Members',
    icon: Icons.User,
  },
  {
    page: RoomSettingsPage.PermissionsPage,
    name: 'Permissions',
    icon: Icons.Lock,
  },
  {
    page: RoomSettingsPage.EmojisStickersPage,
    name: 'Emojis & Stickers',
    icon: Icons.Smile,
  },
  {
    page: RoomSettingsPage.SoundboardPage,
    name: 'Soundboard',
    icon: Icons.Bell,
  },
  {
    page: RoomSettingsPage.DeveloperToolsPage,
    name: 'Developer Tools',
    icon: Icons.Terminal,
  },
  {
    page: RoomSettingsPage.ExportPage,
    name: 'Export',
    icon: Icons.Download,
  },
  {
    page: RoomSettingsPage.ActivityLogPage,
    name: 'Activity',
    icon: Icons.RecentClock,
  },
  {
    page: RoomSettingsPage.InsightsPage,
    name: 'Insights',
    icon: Icons.Info,
  },
];

const SERVER_ACL_MENU_ITEM: RoomSettingsMenuItem = {
  page: RoomSettingsPage.ServerACLPage,
  name: 'Server ACL',
  icon: Icons.Shield,
};

const POLICY_LISTS_MENU_ITEM: RoomSettingsMenuItem = {
  page: RoomSettingsPage.PolicyListsPage,
  name: 'Policy Lists',
  icon: Icons.NoEntry,
};

function useRoomSettingsMenuItems(
  canSeeServerACL: boolean,
  canSeePolicyLists: boolean,
): RoomSettingsMenuItem[] {
  return useMemo(() => {
    const items = [...BASE_MENU_ITEMS];
    if (canSeeServerACL) items.push(SERVER_ACL_MENU_ITEM);
    if (canSeePolicyLists) items.push(POLICY_LISTS_MENU_ITEM);
    return items;
  }, [canSeeServerACL, canSeePolicyLists]);
}

type RoomSettingsProps = {
  initialPage?: RoomSettingsPage;
  requestClose: () => void;
};
export function RoomSettings({ initialPage, requestClose }: RoomSettingsProps) {
  const room = useRoom();
  const mx = useMatrixClient();
  const useAuthentication = useMediaAuthentication();
  const mDirects = useAtomValue(mDirectAtom);

  const roomAvatar = useRoomAvatar(room, mDirects.has(room.roomId));
  const roomName = useRoomName(room);
  const joinRuleContent = useRoomJoinRule(room);

  const avatarUrl = roomAvatar
    ? (mxcUrlToHttp(mx, roomAvatar, useAuthentication, 96, 96, 'crop') ?? undefined)
    : undefined;

  // Power level check: show Server ACL menu item to anyone who can read the state
  // (i.e. has at least state_default power level, or a custom ACL event power).
  // We show it to all users at or above the required power level; read-only view
  // for those who cannot edit.
  const powerLevels = usePowerLevels(room);
  const creators = useRoomCreators(room);
  const myUserId = mx.getSafeUserId();
  const myPL = readPowerLevel.user(powerLevels, myUserId);
  const requiredPL = readPowerLevel.state(powerLevels, StateEvent.RoomServerAcl);
  // Show the menu item if user meets the power level OR is a room creator.
  const canSeeServerACL = myPL >= requiredPL || creators.has(myUserId);
  // Show Policy Lists to admins (power level 50+) or creators.
  const canSeePolicyLists = myPL >= 50 || creators.has(myUserId);

  const screenSize = useScreenSizeContext();
  const [activePage, setActivePage] = useState<RoomSettingsPage | undefined>(() => {
    if (initialPage) return initialPage;
    return screenSize === ScreenSize.Mobile ? undefined : RoomSettingsPage.GeneralPage;
  });
  const menuItems = useRoomSettingsMenuItems(canSeeServerACL, canSeePolicyLists);

  const handlePageRequestClose = () => {
    if (screenSize === ScreenSize.Mobile) {
      setActivePage(undefined);
      return;
    }
    requestClose();
  };

  return (
    <PageRoot
      nav={
        screenSize === ScreenSize.Mobile && activePage !== undefined ? undefined : (
          <PageNav size="300">
            <PageNavHeader outlined={false}>
              <Box grow="Yes" gap="200">
                <Avatar size="200" radii="300">
                  <RoomAvatar
                    roomId={room.roomId}
                    src={avatarUrl}
                    alt={roomName}
                    renderFallback={() => (
                      <RoomIcon
                        size="50"
                        roomType={room.getType()}
                        joinRule={joinRuleContent?.join_rule ?? JoinRule.Invite}
                        filled
                      />
                    )}
                  />
                </Avatar>
                <Text size="H4" truncate>
                  {roomName}
                </Text>
              </Box>
              <Box shrink="No">
                {screenSize === ScreenSize.Mobile && (
                  <IconButton
                    onClick={requestClose}
                    variant="Background"
                    aria-label="Close settings"
                  >
                    <Icon src={Icons.Cross} />
                  </IconButton>
                )}
              </Box>
            </PageNavHeader>
            <Box grow="Yes" direction="Column">
              <PageNavContent>
                <div style={{ flexGrow: 1 }}>
                  {menuItems.map((item) => (
                    <MenuItem
                      key={item.name}
                      variant="Background"
                      radii="400"
                      aria-pressed={activePage === item.page}
                      before={<Icon src={item.icon} size="100" filled={activePage === item.page} />}
                      onClick={() => setActivePage(item.page)}
                    >
                      <Text
                        style={{
                          fontWeight: activePage === item.page ? config.fontWeight.W600 : undefined,
                        }}
                        size="T300"
                        truncate
                      >
                        {item.name}
                      </Text>
                    </MenuItem>
                  ))}
                </div>
              </PageNavContent>
            </Box>
          </PageNav>
        )
      }
    >
      {activePage === RoomSettingsPage.GeneralPage && (
        <General requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.MembersPage && (
        <Members requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.PermissionsPage && (
        <Permissions requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.EmojisStickersPage && (
        <EmojisStickers requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.SoundboardPage && (
        <Soundboard requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.DeveloperToolsPage && (
        <DeveloperTools requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.ExportPage && (
        <ExportRoomHistory requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.ActivityLogPage && (
        <RoomActivityLog requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.ServerACLPage && (
        <RoomServerACL requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.InsightsPage && (
        <RoomInsights requestClose={handlePageRequestClose} />
      )}
      {activePage === RoomSettingsPage.PolicyListsPage && (
        <PolicyListViewer requestClose={handlePageRequestClose} />
      )}
    </PageRoot>
  );
}
