import { useRef, useState } from 'react';

import Menu from '@design-system/Menu';
import MenuItem from '@design-system/Menu/components/MenuItem';
import { IconButton, Stack, TextField, Typography } from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import {
  IconChevronDown,
  IconCopy,
  IconCornerUpLeft,
  IconMoodSmile,
  IconPin,
  IconShare,
} from '@tabler/icons-react';

import IconSelector, { GifPickerProvider } from '.';

const defaultIcon = <IconMoodSmile size={24} />;

const meta: Meta<typeof IconSelector> = {
  component: IconSelector,
  title: 'Design System/IconSelector',
  tags: ['autodocs'],
  args: { icon: defaultIcon, mode: 'emoji' },
  decorators: [
    Story => (
      <Stack
        sx={{
          minHeight: 300,
          bgcolor: theme => theme.palette.new.background.layout.default,
          width: '100%',
          py: 4,
        }}
      >
        <Story />
      </Stack>
    ),
  ],
};

export default meta;

type Story = StoryObj<typeof IconSelector>;

export const Default: Story = {
  tags: ['!autodocs'],
  render: args => (
    <GifPickerProvider apiKey={import.meta.env.VITE_GIPHY_API_KEY ?? ''}>
      <IconSelector {...args} />
    </GifPickerProvider>
  ),
  args: {
    mode: 'emoji-and-gif',
    onEmojiSelect: data => {
      console.log('Selected emoji', data);
    },
    onGifSelect: gif => {
      console.log('Selected GIF', gif);
    },
  },
};

/** Emoji picker stays open after selecting an emoji; close with click outside or ESC. */
/** Trigger with only text (no icon). */
export const KeepOpenOnEmojiSelect: Story = {
  args: {
    text: 'Emoji',
    icon: undefined,
    closeOnEmojiSelect: false,
    onEmojiSelect: data => {
      console.log('Selected emoji', data);
    },
  },
};

/** Gif tab only: no tab bar, only the Gif picker with title. */
export const GifOnly: Story = {
  render: args => (
    <GifPickerProvider apiKey={import.meta.env.VITE_GIPHY_API_KEY ?? ''}>
      <IconSelector {...args} />
    </GifPickerProvider>
  ),
  args: {
    mode: 'gif',
    icon: defaultIcon,
    text: 'GIF',
    slotProps: { text: { gifTitle: 'Choose a GIF' } },
    onGifSelect: gif => {
      console.log('Selected GIF', gif);
    },
  },
};

/** Gif tab only without GifPickerProvider: trigger is disabled. */
export const GifOnlyWithoutProvider: Story = {
  args: {
    mode: 'gif',
    icon: defaultIcon,
    text: 'GIF',
    slotProps: { text: { gifTitle: 'Choose a GIF' } },
  },
};

/** Emoji + GIF tabs without GifPickerProvider: emojis work; GIF tab has no API key. */
export const EmojiAndGifWithoutProvider: Story = {
  args: {
    mode: 'emoji-and-gif',
    icon: defaultIcon,
    onEmojiSelect: data => {
      console.log('Selected emoji', data);
    },
    onGifSelect: gif => {
      console.log('Selected GIF', gif);
    },
  },
};

const SIDEBAR_WIDTH = 240;
const CONTAINED_CHAT_HEIGHT = 380;

/** Chat-like container with only bubbles. IconSelector uses disablePortal so the menu is clipped and does not escape the container. */
export const ContainedInChat: Story = {
  render: args => (
    <GifPickerProvider apiKey={import.meta.env.VITE_GIPHY_API_KEY ?? ''}>
      <Stack
        direction="row"
        sx={{
          overflow: 'hidden',
          maxHeight: CONTAINED_CHAT_HEIGHT,
          width: '100%',
          border: 1,
          borderColor: theme => theme.palette.new.border.neutral.divider,
          borderRadius: 2,
        }}
      >
        {/* Mock sidebar */}
        <Stack
          sx={{
            width: SIDEBAR_WIDTH,
            flexShrink: 0,
            borderRight: theme =>
              `1px solid ${theme.palette.new.border.neutral.divider}`,
            bgcolor: theme => theme.palette.new.background.layout.tertiary,
            py: 2,
            px: 1.5,
          }}
        >
          <Stack sx={{ gap: 0.5 }}>
            {[1, 2, 3].map(i => (
              <Stack
                key={i}
                sx={{
                  height: 40,
                  borderRadius: 1,
                  bgcolor: theme =>
                    i === 1
                      ? theme.palette.new.background.elements.default
                      : 'transparent',
                }}
              />
            ))}
          </Stack>
        </Stack>
        {/* Chat content: bubbles only, overflow hidden so menu stays inside */}
        <Stack
          sx={{
            flex: 1,
            minHeight: 0,
            overflow: 'hidden',
            gap: 2,
            px: 2,
            py: 2,
          }}
        >
          <Stack
            sx={{
              alignSelf: 'flex-start',
              width: 280,
              height: 72,
              borderTopRightRadius: '16px',
              borderBottomRightRadius: theme => theme.shape.borderRadiusL,
              borderBottomLeftRadius: theme => theme.shape.borderRadiusL,
              bgcolor: theme => theme.palette.newBase?.brand[200],
            }}
          />
          <Stack
            sx={{
              flexDirection: 'row',
              gap: 2,
              alignSelf: 'flex-end',
              alignItems: 'center',
            }}
          >
            <IconSelector
              {...args}
              mode="emoji"
              slotProps={{ menu: { disablePortal: true } }}
              onEmojiSelect={data => {
                console.log('Selected emoji', data);
              }}
            />
            <Stack
              sx={{
                width: 280,
                height: 72,
                borderTopLeftRadius: '16px',
                borderBottomRightRadius: theme => theme.shape.borderRadiusL,
                borderBottomLeftRadius: theme => theme.shape.borderRadiusL,
                bgcolor: theme => theme.palette.newBase?.brand[200],
              }}
            />
          </Stack>
        </Stack>
      </Stack>
    </GifPickerProvider>
  ),
  args: {
    icon: defaultIcon,
  },
};

const MESSAGE_MENU_ITEMS = [
  { id: 'reply', label: 'Reply', icon: <IconCornerUpLeft size={18} /> },
  { id: 'forward', label: 'Forward', icon: <IconShare size={18} /> },
  { id: 'copy', label: 'Copy', icon: <IconCopy size={18} /> },
  { id: 'react', label: 'React', icon: <IconMoodSmile size={18} /> },
  { id: 'pin', label: 'Pin', icon: <IconPin size={18} /> },
] as const;

type MessageMenuItemId = (typeof MESSAGE_MENU_ITEMS)[number]['id'];

const MOCK_MESSAGES = [
  { id: 1, side: 'left', author: 'Nico Limo', text: 'Hey! How are you doing?' },
  { id: 2, side: 'right', text: 'All good, thanks! What about you?' },
  {
    id: 3,
    side: 'left',
    author: 'Nico Limo',
    text: 'Doing great. Did you check the new design?',
  },
  { id: 4, side: 'right', text: 'Yes, looks awesome! Really clean.' },
  {
    id: 5,
    side: 'left',
    author: 'Nico Limo',
    text: 'Glad you liked it. We still need to review the icon selector behavior.',
  },
  {
    id: 6,
    side: 'right',
    text: 'Sure, I tested it and the closeOnScroll works perfectly.',
  },
  {
    id: 7,
    side: 'left',
    author: 'Nico Limo',
    text: 'Otro mensaje largo de prueba para ver los sizes que tenemos en el chat list aca largo',
  },
] as const;

const ChatScreenWithReactMenuRender = ({
  args,
}: {
  args: Parameters<NonNullable<Story['render']>>[0];
}) => {
  const [emojiOpen, setEmojiOpen] = useState(false);
  const [menuOpen, setMenuOpen] = useState(false);
  const menuAnchorRef = useRef<HTMLButtonElement | null>(null);

  const onMenuItemClick = (id: MessageMenuItemId) => {
    setMenuOpen(false);
    if (id === 'react') {
      requestAnimationFrame(() => setEmojiOpen(true));
    }
  };

  return (
    <GifPickerProvider apiKey={import.meta.env.VITE_GIPHY_API_KEY ?? ''}>
      <Stack
        direction="row"
        sx={{ flex: 1, width: '100%', height: 420 }}
      >
        {/* Mock sidebar */}
        <Stack
          sx={{
            width: SIDEBAR_WIDTH,
            flexShrink: 0,
            borderRight: theme =>
              `1px solid ${theme.palette.new.border.neutral.divider}`,
            bgcolor: theme => theme.palette.new.background.layout.tertiary,
            py: 2,
            px: 1.5,
          }}
        >
          <Stack sx={{ gap: 0.5 }}>
            {[1, 2, 3].map(i => (
              <Stack
                key={i}
                sx={{
                  height: 40,
                  borderRadius: 1,
                  bgcolor: theme =>
                    i === 1
                      ? theme.palette.new.background.elements.default
                      : 'transparent',
                }}
              />
            ))}
          </Stack>
        </Stack>
        {/* Chat content */}
        <Stack sx={{ flex: 1, width: '100%', minWidth: 0, overflow: 'hidden' }}>
          {/* Scrollable messages area */}
          <Stack
            sx={{
              flex: 1,
              gap: 2,
              px: 2,
              py: 2,
              overflowY: 'auto',
            }}
          >
            {MOCK_MESSAGES.map(msg => (
              <Stack
                key={msg.id}
                sx={{
                  alignSelf: msg.side === 'left' ? 'flex-start' : 'flex-end',
                  flexDirection: 'row',
                  alignItems: 'flex-start',
                  gap: 1,
                }}
              >
                {msg.side === 'left' && (
                  <>
                    <Stack
                      sx={{
                        width: 300,
                        p: 2,
                        borderTopRightRadius: '16px',
                        borderBottomRightRadius: theme =>
                          theme.shape.borderRadiusL,
                        borderBottomLeftRadius: theme =>
                          theme.shape.borderRadiusL,
                        bgcolor: theme => theme.palette.newBase?.brand[200],
                      }}
                    >
                      <Typography
                        variant="body2"
                        fontWeight={600}
                      >
                        {msg.author}
                      </Typography>
                      <Typography variant="body2">{msg.text}</Typography>
                    </Stack>
                    <IconButton
                      ref={
                        msg.id === MOCK_MESSAGES[MOCK_MESSAGES.length - 1].id
                          ? menuAnchorRef
                          : undefined
                      }
                      size="small"
                      onClick={() => setMenuOpen(prev => !prev)}
                      aria-label="Message actions"
                      sx={{ mt: 0.5 }}
                    >
                      <IconChevronDown size={16} />
                    </IconButton>
                  </>
                )}
                {msg.side === 'right' && (
                  <Stack
                    sx={{
                      width: 300,
                      p: 2,
                      borderTopLeftRadius: '16px',
                      borderBottomRightRadius: theme =>
                        theme.shape.borderRadiusL,
                      borderBottomLeftRadius: theme =>
                        theme.shape.borderRadiusL,
                      bgcolor: theme =>
                        theme.palette.new.background.elements.default,
                    }}
                  >
                    <Typography variant="body2">{msg.text}</Typography>
                  </Stack>
                )}
              </Stack>
            ))}
            <Menu
              anchorEl={menuAnchorRef.current}
              open={menuOpen}
              onClose={() => setMenuOpen(false)}
              position="right"
            >
              {MESSAGE_MENU_ITEMS.map(item => (
                <MenuItem
                  key={item.id}
                  onClick={() => onMenuItemClick(item.id)}
                >
                  <Stack
                    direction="row"
                    sx={{
                      alignItems: 'center',
                      justifyContent: 'space-between',
                      width: '100%',
                      gap: 2,
                    }}
                  >
                    <Typography variant="body2">{item.label}</Typography>
                    {item.icon}
                  </Stack>
                </MenuItem>
              ))}
            </Menu>
          </Stack>
          {/* Input area */}
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 1,
              px: 2,
              py: 1,
              borderTop: theme =>
                `1px solid ${theme.palette.new.border.neutral.divider}`,
            }}
          >
            <IconSelector
              {...args}
              mode="emoji-and-gif"
              open={emojiOpen}
              onOpenChange={setEmojiOpen}
              closeOnScroll
              onEmojiSelect={data => {
                console.log('Selected emoji', data);
              }}
              onGifSelect={gif => {
                console.log('Selected GIF', gif);
              }}
            />
            <TextField
              placeholder="Write a message..."
              size="small"
              fullWidth
              sx={{ '& fieldset': { borderRadius: 2 } }}
            />
          </Stack>
        </Stack>
      </Stack>
    </GifPickerProvider>
  );
};

/**
 * Chat screen with a message context menu. Choosing "React" opens the same
 * composer IconSelector that the smiley next to the input opens, via the
 * controlled `open` / `onOpenChange` API.
 */
export const ChatScreenWithReactMenu: Story = {
  render: args => <ChatScreenWithReactMenuRender args={args} />,
  args: {
    icon: defaultIcon,
  },
};

/** Chat screen: message bubbles and input. The icon in the right bubble or next to the input opens the IconSelector. */
export const ChatScreen: Story = {
  render: args => (
    <GifPickerProvider apiKey={import.meta.env.VITE_GIPHY_API_KEY ?? ''}>
      <Stack
        direction="row"
        sx={{ flex: 1, width: '100%', minHeight: 400 }}
      >
        {/* Mock sidebar */}
        <Stack
          sx={{
            width: SIDEBAR_WIDTH,
            flexShrink: 0,
            borderRight: theme =>
              `1px solid ${theme.palette.new.border.neutral.divider}`,
            bgcolor: theme => theme.palette.new.background.layout.tertiary,
            py: 2,
            px: 1.5,
          }}
        >
          <Stack sx={{ gap: 0.5 }}>
            {[1, 2, 3].map(i => (
              <Stack
                key={i}
                sx={{
                  height: 40,
                  borderRadius: 1,
                  bgcolor: theme =>
                    i === 1
                      ? theme.palette.new.background.elements.default
                      : 'transparent',
                }}
              />
            ))}
          </Stack>
        </Stack>
        {/* Chat content */}
        <Stack sx={{ flex: 1, width: '100%', gap: 2, minWidth: 0 }}>
          {/* Chat bubbles area */}
          <Stack sx={{ flex: 1, gap: 2, px: 2 }}>
            <Stack
              sx={{
                alignSelf: 'flex-start',
                width: 300,
                height: 80,
                borderTopRightRadius: '16px',
                borderBottomRightRadius: theme => theme.shape.borderRadiusL,
                borderBottomLeftRadius: theme => theme.shape.borderRadiusL,
                bgcolor: theme => theme.palette.newBase?.brand[200],
              }}
            />
            <Stack
              sx={{
                flexDirection: 'row',
                gap: 2,
                alignSelf: 'flex-end',
                alignItems: 'center',
              }}
            >
              <IconSelector
                {...args}
                mode="emoji"
                onEmojiSelect={data => {
                  console.log('Selected emoji', data);
                }}
              />
              <Stack
                sx={{
                  width: 300,
                  height: 80,
                  borderTopLeftRadius: '16px',
                  borderBottomRightRadius: theme => theme.shape.borderRadiusL,
                  borderBottomLeftRadius: theme => theme.shape.borderRadiusL,
                  bgcolor: theme => theme.palette.newBase?.brand[200],
                }}
              />
            </Stack>
          </Stack>
          {/* Input area */}
          <Stack
            sx={{
              flexDirection: 'row',
              alignItems: 'center',
              gap: 1,
              px: 2,
            }}
          >
            <IconSelector
              {...args}
              mode="emoji-and-gif"
              onEmojiSelect={data => {
                console.log('Selected emoji', data);
              }}
              onGifSelect={gif => {
                console.log('Selected GIF', gif);
              }}
            />
            <TextField
              placeholder="Type a message..."
              size="small"
              fullWidth
              sx={{ '& fieldset': { borderRadius: 2 } }}
            />
          </Stack>
        </Stack>
      </Stack>
    </GifPickerProvider>
  ),
  args: {
    icon: defaultIcon,
  },
};
