import { type ElementType } from 'react';

import Pills from '@design-system/Pills';
import { Stack, Typography } from '@mui/material';
import { type Meta, type StoryObj } from '@storybook/react-vite';
import {
  IconCalendarEvent,
  IconClockHour4,
  IconMapPin,
  IconPackage,
  IconTruck,
} from '@tabler/icons-react';

import { type TimelineProps, TrackerOnlyState } from './types';
import Timeline from '.';

type StepPillType =
  | 'success'
  | 'info'
  | 'warning'
  | 'error'
  | 'neutral'
  | 'disabled';

type TimelineStepContentProps = {
  title: string;
  timestamp?: string;
  description?: string;
  pill?: {
    label: string;
    type: StepPillType;
  };
  Icon?: ElementType;
  isDisabled?: boolean;
};

const TimelineStepContent = ({
  title,
  timestamp,
  description,
  pill,
  Icon,
  isDisabled,
}: TimelineStepContentProps) => (
  <Stack
    sx={{
      flex: 1,
      gap: 0.5,
      pb: 3,
      pt: 0.5,
      opacity: isDisabled ? 0.55 : 1,
    }}
  >
    <Stack
      sx={{
        flexDirection: 'row',
        alignItems: 'center',
        gap: 1,
        flexWrap: 'wrap',
      }}
    >
      {Icon && (
        <Icon
          size={18}
          stroke={1.75}
        />
      )}
      <Typography
        variant="globalS"
        sx={{ fontWeight: 'fontWeightSemiBold' }}
      >
        {title}
      </Typography>
      {pill && (
        <Pills
          label={pill.label}
          type={pill.type}
          size="small"
        />
      )}
    </Stack>
    {timestamp && (
      <Typography
        variant="globalXS"
        sx={{ color: theme => theme.palette.new.text.neutral.lighter }}
      >
        {timestamp}
      </Typography>
    )}
    {description && (
      <Typography
        variant="globalXS"
        sx={{ color: theme => theme.palette.new.text.neutral.default }}
      >
        {description}
      </Typography>
    )}
  </Stack>
);

const meta: Meta<typeof Timeline> = {
  component: Timeline,
  title: 'Design System/Timeline',
  tags: ['autodocs'],
  args: {
    state: TrackerOnlyState.COMPLETE,
    continued: true,
    children: (
      <TimelineStepContent
        title="Order placed"
        timestamp="Mon, May 25 · 9:42 AM"
        description="We received your order and sent a confirmation to your email."
        pill={{ label: 'Done', type: 'success' }}
        Icon={IconPackage}
      />
    ),
  },
  argTypes: {
    state: {
      control: 'select',
      options: Object.values(TrackerOnlyState),
      description:
        'Visual state of the tracker. Drives the avatar color/icon and the connector line color.',
    },
    continued: {
      control: 'boolean',
      description:
        'Whether to render the vertical connector line below the avatar. Set to `false` for the last item in the timeline.',
    },
  },
  parameters: {
    layout: 'padded',
  },
};

export default meta;

type Story = StoryObj<typeof Timeline>;

export const Default: Story = {
  render: args => (
    <Stack sx={{ maxWidth: 520 }}>
      <Timeline {...args} />
    </Stack>
  ),
};

export const AllStates: Story = {
  parameters: {
    docs: {
      description: {
        story:
          'Every supported `state` rendered side-by-side so you can compare the avatar and connector treatments.',
      },
    },
  },
  render: () => {
    const stateCopy: Record<
      TrackerOnlyState,
      { title: string; description: string; pillType: StepPillType }
    > = {
      [TrackerOnlyState.COMPLETE]: {
        title: 'Complete',
        description:
          'Step finished successfully. The connector adopts the brand color.',
        pillType: 'success',
      },
      [TrackerOnlyState.CURRENT]: {
        title: 'Current',
        description:
          'Step in progress. The avatar is highlighted with a brand border.',
        pillType: 'info',
      },
      [TrackerOnlyState.DISABLED]: {
        title: 'Disabled',
        description:
          'Upcoming or inactive step. Rendered in a muted neutral tone.',
        pillType: 'disabled',
      },
      [TrackerOnlyState.ERROR]: {
        title: 'Error',
        description:
          'Something went wrong on this step. Uses the feedback error color.',
        pillType: 'error',
      },
    };

    const states = Object.values(TrackerOnlyState);

    return (
      <Stack sx={{ maxWidth: 520 }}>
        {states.map((state, index) => (
          <Timeline
            key={state}
            state={state}
            continued={index < states.length - 1}
          >
            <TimelineStepContent
              title={stateCopy[state].title}
              description={stateCopy[state].description}
              pill={{ label: state, type: stateCopy[state].pillType }}
              isDisabled={state === TrackerOnlyState.DISABLED}
            />
          </Timeline>
        ))}
      </Stack>
    );
  },
};

export const OrderTracking: Story = {
  parameters: {
    docs: {
      description: {
        story:
          'A realistic order-tracking flow. Combine multiple `Timeline` rows and toggle `continued` on the last one to close the timeline.',
      },
    },
  },
  render: () => {
    const steps: Array<{
      state: TrackerOnlyState;
      content: TimelineStepContentProps;
    }> = [
      {
        state: TrackerOnlyState.COMPLETE,
        content: {
          title: 'Order placed',
          timestamp: 'Mon, May 25 · 9:42 AM',
          description: 'Payment confirmed and receipt sent to your inbox.',
          pill: { label: 'Done', type: 'success' },
          Icon: IconPackage,
        },
      },
      {
        state: TrackerOnlyState.COMPLETE,
        content: {
          title: 'Packed at warehouse',
          timestamp: 'Tue, May 26 · 2:18 PM',
          description: 'Your items have been packed and labelled for shipping.',
          pill: { label: 'Done', type: 'success' },
          Icon: IconCalendarEvent,
        },
      },
      {
        state: TrackerOnlyState.CURRENT,
        content: {
          title: 'Out for delivery',
          timestamp: 'Today · 8:05 AM',
          description:
            'Driver is on the way. Estimated arrival between 4 PM and 6 PM.',
          pill: { label: 'In progress', type: 'info' },
          Icon: IconTruck,
        },
      },
      {
        state: TrackerOnlyState.DISABLED,
        content: {
          title: 'Delivered',
          timestamp: 'Estimated today',
          description: 'Signature may be required at the door.',
          pill: { label: 'Pending', type: 'disabled' },
          Icon: IconMapPin,
          isDisabled: true,
        },
      },
    ];

    return (
      <Stack sx={{ maxWidth: 520 }}>
        {steps.map((step, index) => (
          <Timeline
            key={step.content.title}
            state={step.state}
            continued={index < steps.length - 1}
          >
            <TimelineStepContent {...step.content} />
          </Timeline>
        ))}
      </Stack>
    );
  },
};

export const WithErrorStep: Story = {
  parameters: {
    docs: {
      description: {
        story:
          'The `ERROR` state is useful to highlight a failed step in an otherwise normal flow. Remaining steps can be kept as `DISABLED` while the error is resolved.',
      },
    },
  },
  render: () => {
    const steps: Array<
      Pick<TimelineProps, 'state'> & {
        content: TimelineStepContentProps;
      }
    > = [
      {
        state: TrackerOnlyState.COMPLETE,
        content: {
          title: 'Identity verified',
          timestamp: 'Step 1 of 3',
          description: 'We confirmed your ID document and selfie match.',
          pill: { label: 'Verified', type: 'success' },
        },
      },
      {
        state: TrackerOnlyState.ERROR,
        content: {
          title: 'Bank account validation failed',
          timestamp: 'Step 2 of 3',
          description:
            'The account holder name does not match the one on file. Please update your details and try again.',
          pill: { label: 'Action required', type: 'error' },
        },
      },
      {
        state: TrackerOnlyState.DISABLED,
        content: {
          title: 'Final review',
          timestamp: 'Step 3 of 3',
          description:
            'We will review the information once the previous step is resolved.',
          pill: { label: 'On hold', type: 'disabled' },
          isDisabled: true,
        },
      },
    ];

    return (
      <Stack sx={{ maxWidth: 520 }}>
        {steps.map((step, index) => (
          <Timeline
            key={step.content.title}
            state={step.state}
            continued={index < steps.length - 1}
          >
            <TimelineStepContent {...step.content} />
          </Timeline>
        ))}
      </Stack>
    );
  },
};

export const SingleItem: Story = {
  parameters: {
    docs: {
      description: {
        story:
          'Set `continued={false}` to hide the connector line. Useful for a single-item timeline or the last step in a flow.',
      },
    },
  },
  args: {
    state: TrackerOnlyState.CURRENT,
    continued: false,
    children: (
      <TimelineStepContent
        title="Awaiting your approval"
        timestamp="Updated 5 min ago"
        description="Review the request and approve to continue. No connector line is rendered when `continued` is false."
        pill={{ label: 'Awaiting', type: 'info' }}
        Icon={IconClockHour4}
      />
    ),
  },
  render: args => (
    <Stack sx={{ maxWidth: 520 }}>
      <Timeline {...args} />
    </Stack>
  ),
};
