import { useState } from 'react';
import { FormProvider, useForm } from 'react-hook-form';

import { Box, Button, Card, Stack, Typography } from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import { IconEdit, IconTrash } from '@tabler/icons-react';

import FormInputClassic from '../../design-system/Inputs/Classic/form';

import { type BaseSortableItem, type ItemComponentProps } from './types';
import SortableList from '.';

// Type for list items
type SimpleItem = BaseSortableItem & {
  title: string;
};

// Type for items with form
type FormItem = BaseSortableItem & {
  title: string;
  description: string;
  email: string;
};

// Simple card component with title and two buttons
const SimpleCard: React.FC<ItemComponentProps<SimpleItem>> = ({
  item,
  dragHandleButton,
}) => {
  return (
    <Card
      sx={{ p: 2, border: '1px solid #e0e0e0' }}
      elevation={0}
      variant="outlined"
    >
      <Stack
        direction="row"
        spacing={2}
      >
        {dragHandleButton}
        <Stack
          direction="row"
          alignItems="center"
          justifyContent="space-between"
          sx={{ mb: 2, flex: 1 }}
        >
          <Typography
            variant="h6"
            component="div"
          >
            {item.title}
          </Typography>
        </Stack>
        <Stack
          direction="row"
          spacing={1}
        >
          <Button
            variant="outlined"
            size="small"
            startIcon={<IconEdit size={16} />}
            onClick={() => alert(`Editar: ${item.title}`)}
          >
            Editar
          </Button>
          <Button
            variant="outlined"
            color="error"
            size="small"
            startIcon={<IconTrash size={16} />}
            onClick={() => alert(`Eliminar: ${item.title}`)}
          >
            Eliminar
          </Button>
        </Stack>
      </Stack>
    </Card>
  );
};

// Card component with form
const FormCard: React.FC<ItemComponentProps<FormItem>> = ({
  item,
  dragHandleButton,
}) => {
  const form = useForm({
    defaultValues: {
      title: item.title,
      description: item.description,
      email: item.email,
    },
  });

  const handleSave = () => {
    const values = form.getValues();
    alert(`Guardando: ${JSON.stringify(values, null, 2)}`);
  };

  return (
    <Card
      sx={{ p: 2, border: '1px solid #e0e0e0', minWidth: 300 }}
      elevation={0}
      variant="outlined"
    >
      <FormProvider {...form}>
        <Stack spacing={2}>
          <Stack
            direction="row"
            alignItems="center"
            justifyContent="space-between"
          >
            <Typography
              variant="h6"
              component="div"
            >
              Formulario #{item.id}
            </Typography>
            {dragHandleButton}
          </Stack>

          <FormInputClassic
            name="title"
            inputProps={{
              label: 'Título',
              placeholder: 'Ingresa el título',
              size: 'small',
              hasCounter: false,
            }}
            rules={{ required: 'El título es requerido' }}
          />

          <FormInputClassic
            name="description"
            inputProps={{
              label: 'Descripción',
              placeholder: 'Ingresa la descripción',
              size: 'small',
              hasCounter: false,
            }}
          />

          <FormInputClassic
            name="email"
            inputProps={{
              label: 'Email',
              placeholder: 'ejemplo@correo.com',
              type: 'email',
              size: 'small',
              hasCounter: false,
            }}
            rules={{
              required: 'El email es requerido',
              pattern: {
                value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
                message: 'Email inválido',
              },
            }}
          />

          <Stack
            direction="row"
            spacing={1}
            justifyContent="flex-end"
          >
            <Button
              variant="outlined"
              size="small"
              onClick={handleSave}
            >
              Guardar
            </Button>
            <Button
              variant="outlined"
              color="error"
              size="small"
              startIcon={<IconTrash size={16} />}
              onClick={() => alert(`Eliminar formulario: ${item.id}`)}
            >
              Eliminar
            </Button>
          </Stack>
        </Stack>
      </FormProvider>
    </Card>
  );
};

const meta: Meta<typeof SortableList> = {
  component: SortableList,
  title: 'Composed Components/SortableList',
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component:
          'A sortable list component that allows you to drag and drop items to reorder them. Supports vertical and horizontal direction, and can be configured to drag only by the handle.',
      },
    },
  },
  argTypes: {
    direction: {
      control: 'radio',
      options: ['vertical', 'horizontal'],
      description: 'List direction',
    },
    dragByHandler: {
      control: 'boolean',
      description: 'If true, you can only drag using the handle',
    },
  },
};

export default meta;

// Base story with example data
const baseItems: SimpleItem[] = [
  { id: '1', title: 'Tarea 1' },
  { id: '2', title: 'Tarea 2' },
  { id: '3', title: 'Tarea 3' },
  { id: '4', title: 'Tarea 4' },
  { id: '5', title: 'Tarea 5' },
];

// Base story with example data for forms
const formItems: FormItem[] = [
  {
    id: '1',
    title: 'Usuario 1',
    description: 'Descripción del usuario 1',
    email: 'usuario1@ejemplo.com',
  },
  {
    id: '2',
    title: 'Usuario 2',
    description: 'Descripción del usuario 2',
    email: 'usuario2@ejemplo.com',
  },
  {
    id: '3',
    title: 'Usuario 3',
    description: 'Descripción del usuario 3',
    email: 'usuario3@ejemplo.com',
  },
];

// Story 1: Vertical list with full drag
export const VerticalList: StoryObj<typeof SortableList<SimpleItem>> = {
  args: {
    items: baseItems,
    ItemComponent: SimpleCard,
    direction: 'vertical',
    dragByHandler: false,
    sx: { gap: 2 },
    onSort: (sortedItems: SimpleItem[]) => {
      return sortedItems;
    },
  },
  render: args => {
    const [items, setItems] = useState(args.items);

    return (
      <Box sx={{ p: 2, maxWidth: 400 }}>
        <Typography
          variant="h6"
          sx={{ mb: 2 }}
        >
          Vertical List - Full Drag
        </Typography>
        <Typography
          variant="body2"
          color="text.secondary"
          sx={{ mb: 2 }}
        >
          You can drag any part of the card to reorder
        </Typography>
        <SortableList
          {...args}
          items={items}
          onSort={setItems}
        />
      </Box>
    );
  },
};

// Story 2: Vertical list with drag only by handle
export const VerticalListWithHandle: StoryObj<typeof SortableList<SimpleItem>> =
  {
    args: {
      items: baseItems,
      ItemComponent: SimpleCard,
      direction: 'vertical',
      dragByHandler: true,
      sx: { gap: 2 },
      onSort: sortedItems => {
        return sortedItems;
      },
    },
    render: args => {
      const [items, setItems] = useState(args.items);

      return (
        <Box sx={{ p: 2, maxWidth: 400 }}>
          <Typography
            variant="h6"
            sx={{ mb: 2 }}
          >
            Vertical List - Drag by Handle
          </Typography>
          <Typography
            variant="body2"
            color="text.secondary"
            sx={{ mb: 2 }}
          >
            You can only drag using the handle icon in the top right corner
          </Typography>
          <SortableList
            {...args}
            items={items}
            onSort={setItems}
          />
        </Box>
      );
    },
  };

// Story 3: Horizontal list with full drag
export const HorizontalList: StoryObj<typeof SortableList<SimpleItem>> = {
  args: {
    items: baseItems,
    ItemComponent: SimpleCard,
    direction: 'horizontal',
    dragByHandler: false,
    sx: { gap: 2 },
    onSort: sortedItems => {
      return sortedItems;
    },
  },
  render: args => {
    const [items, setItems] = useState(args.items);

    return (
      <Box sx={{ p: 2 }}>
        <Typography
          variant="h6"
          sx={{ mb: 2 }}
        >
          Horizontal List - Full Drag
        </Typography>
        <Typography
          variant="body2"
          color="text.secondary"
          sx={{ mb: 2 }}
        >
          You can drag any part of the card to reorder horizontally
        </Typography>
        <SortableList
          {...args}
          items={items}
          onSort={setItems}
        />
      </Box>
    );
  },
};

// Story 4: Horizontal list with drag only by handle
export const HorizontalListWithHandle: StoryObj<
  typeof SortableList<SimpleItem>
> = {
  args: {
    items: baseItems,
    ItemComponent: SimpleCard,
    direction: 'horizontal',
    dragByHandler: true,
    sx: { gap: 2 },
    onSort: sortedItems => {
      return sortedItems;
    },
  },
  render: args => {
    const [items, setItems] = useState(args.items);

    return (
      <Box sx={{ p: 2 }}>
        <Typography
          variant="h6"
          sx={{ mb: 2 }}
        >
          Horizontal List - Drag by Handle
        </Typography>
        <Typography
          variant="body2"
          color="text.secondary"
          sx={{ mb: 2 }}
        >
          You can only drag using the handle icon in the top right corner
        </Typography>
        <SortableList
          {...args}
          items={items}
          onSort={setItems}
        />
      </Box>
    );
  },
};

// Story 5: Vertical list with forms
export const VerticalFormList: StoryObj<typeof SortableList<FormItem>> = {
  args: {
    items: formItems,
    ItemComponent: FormCard,
    direction: 'vertical',
    dragByHandler: true,
    sx: { gap: 2 },
    onSort: sortedItems => {
      return sortedItems;
    },
  },
  render: args => {
    const [items, setItems] = useState(args.items);

    return (
      <Box sx={{ p: 2, maxWidth: 500 }}>
        <Typography
          variant="h6"
          sx={{ mb: 2 }}
        >
          Form List - Drag by Handle
        </Typography>
        <Typography
          variant="body2"
          color="text.secondary"
          sx={{ mb: 2 }}
        >
          Drag the forms using the handle to reorder them. The forms are fully
          functional.
        </Typography>
        <SortableList
          {...args}
          items={items}
          onSort={setItems}
        />
      </Box>
    );
  },
};

// Story 6: Horizontal list with forms
export const HorizontalFormList: StoryObj<typeof SortableList<FormItem>> = {
  args: {
    items: formItems,
    ItemComponent: FormCard,
    direction: 'horizontal',
    dragByHandler: true,
    sx: { gap: 2 },
    onSort: sortedItems => {
      return sortedItems;
    },
  },
  render: args => {
    const [items, setItems] = useState(args.items);

    return (
      <Box sx={{ p: 2 }}>
        <Typography
          variant="h6"
          sx={{ mb: 2 }}
        >
          Horizontal Form List - Drag by Handle
        </Typography>
        <Typography
          variant="body2"
          color="text.secondary"
          sx={{ mb: 2 }}
        >
          Drag the forms horizontally using the handle. The forms include
          validation.
        </Typography>
        <SortableList
          {...args}
          items={items}
          onSort={setItems}
        />
      </Box>
    );
  },
};
