import React, { ReactNode } from 'react';
import styled, { keyframes } from 'styled-components';
import { Spinner } from '@/shared/components/ui/Spinner';
import { Button } from '@/shared/components/ui/Button';

const fadeIn = keyframes`
  from {
    opacity: 0;
    transform: translateY(6px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
`;

export const PanelLoading = styled.div.attrs({ role: 'status' })`
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: ${({ theme }) => theme.spacing[4]};
  padding: ${({ theme }) => theme.spacing[12]} ${({ theme }) => theme.spacing[6]};
  color: ${({ theme }) => theme.colors.text.secondary};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
`;

export const PanelMessage = styled.p<{ $variant?: 'error' | 'warning' | 'muted' }>`
  margin: 0;
  text-align: start;
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  line-height: ${({ theme }) => theme.typography.lineHeight.relaxed};
  color: ${({ theme, $variant }) => {
    switch ($variant) {
      case 'error':
        return theme.colors.error;
      case 'warning':
        return theme.colors.warningDark;
      default:
        return theme.colors.text.secondary;
    }
  }};
`;

const EmptyWrap = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  padding: ${({ theme }) => theme.spacing[10]} ${({ theme }) => theme.spacing[6]};
  animation: ${fadeIn} 0.28s ease-out;
`;

const EmptyIcon = styled.div`
  width: 52px;
  height: 52px;
  border-radius: ${({ theme }) => theme.borderRadius.xl};
  background: ${({ theme }) => theme.colors.primary}12;
  color: ${({ theme }) => theme.colors.primary};
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.375rem;
  margin-bottom: ${({ theme }) => theme.spacing[4]};
`;

const EmptyTitle = styled.p`
  margin: 0 0 ${({ theme }) => theme.spacing[2]};
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};
  color: ${({ theme }) => theme.colors.text.primary};
`;

const EmptyHint = styled.p`
  margin: 0;
  max-width: 22rem;
  font-size: ${({ theme }) => theme.typography.fontSize.xs};
  color: ${({ theme }) => theme.colors.text.tertiary};
  line-height: ${({ theme }) => theme.typography.lineHeight.relaxed};
`;

interface PanelEmptyProps {
  icon?: ReactNode;
  title: string;
  hint?: string;
}

export const PanelEmpty: React.FC<PanelEmptyProps> = ({ icon, title, hint }) => (
  <EmptyWrap role="status">
    {icon && <EmptyIcon aria-hidden>{icon}</EmptyIcon>}
    <EmptyTitle>{title}</EmptyTitle>
    {hint && <EmptyHint>{hint}</EmptyHint>}
  </EmptyWrap>
);

const ErrorWrap = styled.div`
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[4]};
  padding: ${({ theme }) => theme.spacing[10]} ${({ theme }) => theme.spacing[6]};
  text-align: center;

  ${PanelMessage} {
    text-align: center;
  }
`;

interface PanelErrorProps {
  message: string;
  retryLabel?: string;
  onRetry?: () => void;
  loading?: boolean;
}

export const PanelError: React.FC<PanelErrorProps> = ({
  message,
  retryLabel,
  onRetry,
  loading,
}) => (
  <ErrorWrap role="alert">
    <PanelMessage $variant="error">{message}</PanelMessage>
    {retryLabel && onRetry && (
      <Button variant="primary" size="sm" onClick={onRetry} loading={loading}>
        {retryLabel}
      </Button>
    )}
  </ErrorWrap>
);

interface PanelLoadingWithLabelProps {
  label?: string;
}

export const PanelLoadingState: React.FC<PanelLoadingWithLabelProps> = ({ label }) => (
  <PanelLoading aria-live="polite">
    <Spinner size="lg" />
    {label && <span>{label}</span>}
  </PanelLoading>
);
