import {
  Box,
  Dialog,
  DialogActions,
  DialogContent,
  DialogContentProps,
  DialogProps,
  DialogTitle,
  DialogTitleProps,
  IconButton,
  Stack,
  SxProps,
  Theme
} from '@linagora/twake-mui'
import ArrowBackIcon from '@mui/icons-material/ArrowBack'
import CloseIcon from '@mui/icons-material/Close'
import OpenInFullIcon from '@mui/icons-material/OpenInFull'
import CozyBridge from 'cozy-external-bridge'
import React, { ReactNode, useMemo } from 'react'

/**
 * ResponsiveDialog - A reusable dialog component that can switch between normal and expanded modes
 *
 * Features:
 * - Normal mode: Dialog with customizable max-width (default 570px)
 * - Expanded mode: Full height dialog (excluding app header) with centered content container
 * - Fully customizable with sx props for Dialog, DialogTitle, and DialogContent
 * - Preserves app header visibility in expanded mode
 *
 * @example
 * ```tsx
 * <ResponsiveDialog
 *   open={open}
 *   onClose={handleClose}
 *   title="My Dialog"
 *   isExpanded={showMore}
 *   actions={<Button onClick={handleSave}>Save</Button>}
 *   contentSx={{ padding: 3 }}
 * >
 *   <TextField label="Name" />
 * </ResponsiveDialog>
 * ```
 */
interface ResponsiveDialogProps extends Omit<
  DialogProps,
  'maxWidth' | 'title'
> {
  /** Whether the dialog is open */
  open: boolean
  /** Callback fired when the dialog should be closed */
  onClose: () => void
  /** Dialog title - can be string or custom ReactNode */
  title: string | ReactNode
  /** Dialog content - form fields, text, etc. */
  children: ReactNode
  /** Optional actions rendered in DialogActions (buttons, etc.) */
  actions?: ReactNode
  /** Toggle between normal and expanded (fullscreen) mode */
  isExpanded?: boolean
  /** Callback when expand/collapse button is clicked (required if using isExpanded) */
  onExpandToggle?: () => void
  /** Max width in normal mode (default: "570px") */
  normalMaxWidth?: string
  /** Max width of content container in expanded mode (default: "990px") */
  expandedContentMaxWidth?: string
  /** Height of app header to preserve visibility (default: "90px") */
  headerHeight?: string
  /** Spacing between children in normal mode (default: 2 = 16px) */
  normalSpacing?: number
  /** Spacing between children in expanded mode (default: 2 = 16px) */
  expandedSpacing?: number
  /** Custom styles for DialogContent - merged with base styles */
  contentSx?: SxProps<Theme>
  /** Custom styles for DialogTitle */
  titleSx?: SxProps<Theme>
  /** Additional props for DialogContent (excluding sx) */
  dialogContentProps?: Omit<DialogContentProps, 'sx'>
  /** Additional props for DialogTitle (excluding sx) */
  dialogTitleProps?: Omit<DialogTitleProps, 'sx'>
  /** Whether to display dividers between title/content/actions */
  dividers?: boolean
  /** Whether to show header action icons (expand/close) in normal mode (default: true) */
  showHeaderActions?: boolean
  /** Whether to add border-top to DialogActions */
  actionsBorderTop?: boolean
  /** Justify content alignment for DialogActions */
  actionsJustifyContent?: 'flex-start' | 'center' | 'flex-end' | 'space-between'
}

function ResponsiveDialog({
  open,
  onClose,
  title,
  children,
  actions,
  isExpanded = false,
  onExpandToggle,
  normalMaxWidth = '570px',
  expandedContentMaxWidth = '990px',
  headerHeight = '70px',
  normalSpacing = 2,
  expandedSpacing = 2,
  contentSx,
  titleSx,
  dialogContentProps,
  dialogTitleProps,
  dividers = false,
  showHeaderActions = true,
  actionsBorderTop = false,
  actionsJustifyContent = 'flex-end',
  sx,
  ...otherDialogProps
}: ResponsiveDialogProps) {
  const isInIframe = useMemo(() => new CozyBridge().isInIframe(), [])
  const baseSx: SxProps<Theme> = {
    '& .MuiBackdrop-root': {
      backgroundColor: 'rgba(0, 0, 0, 0.1)',
      opacity: isExpanded ? '0 !important' : undefined,
      transition: isExpanded ? 'none !important' : undefined,
      pointerEvents: isExpanded ? 'none' : undefined
    },
    '& .MuiDialog-paper': {
      maxWidth: isExpanded ? '100%' : normalMaxWidth,
      width: '100%',
      height: isExpanded
        ? `calc(100vh - ${isInIframe ? '0px' : headerHeight})`
        : undefined,
      maxHeight: isExpanded && isInIframe ? '100%' : undefined,
      margin: isExpanded ? `${isInIframe ? 0 : headerHeight} 0 0 0` : '32px',
      boxShadow: isExpanded ? 'none !important' : undefined,
      transition: isExpanded ? 'none !important' : undefined,
      zIndex: isExpanded ? 1200 : 1300
    },
    '& .MuiDialogActions-root .MuiBox-root': {
      maxWidth: isExpanded ? expandedContentMaxWidth : undefined,
      margin: isExpanded ? '0 auto' : undefined,
      padding: '0',
      width: isExpanded ? '100%' : undefined,
      justifyContent: isExpanded ? 'flex-end' : undefined
    }
  }

  const baseContentSx: SxProps<Theme> = {
    width: '100%'
  }

  const contentWrapperSx: SxProps<Theme> = {
    maxWidth: isExpanded ? expandedContentMaxWidth : '100%',
    margin: isExpanded ? '0 auto' : '0',
    width: '100%'
  }

  React.useEffect(() => {
    if (isExpanded) {
      document.body.classList.add('fullscreen-view')
    } else {
      document.body.classList.remove('fullscreen-view')
    }
  }, [isExpanded])

  const handleClose = (
    event: unknown,
    reason: 'backdropClick' | 'escapeKeyDown'
  ) => {
    if (isExpanded && reason === 'backdropClick') {
      return
    }
    onClose()
  }

  const currentSpacing = isExpanded ? expandedSpacing : normalSpacing

  return (
    <Dialog
      open={open}
      onClose={handleClose}
      maxWidth={false}
      fullWidth
      transitionDuration={isExpanded ? 0 : 300}
      sx={[baseSx, ...(Array.isArray(sx) ? sx : [sx])]}
      style={isExpanded ? { zIndex: 1200 } : undefined}
      {...otherDialogProps}
    >
      <DialogTitle sx={titleSx} {...dialogTitleProps}>
        {isExpanded && onExpandToggle ? (
          <IconButton
            onClick={onExpandToggle}
            aria-label="show less"
            sx={{ marginLeft: '-8px' }}
          >
            <ArrowBackIcon sx={{ color: '#605D62', fontSize: 30 }} />
          </IconButton>
        ) : showHeaderActions ? (
          <Box
            display="flex"
            justifyContent="space-between"
            alignItems="center"
            width="100%"
          >
            <Box>{title}</Box>
            <Box>
              {onExpandToggle && (
                <IconButton
                  onClick={onExpandToggle}
                  aria-label="expand"
                  size="small"
                  sx={{ marginRight: 1 }}
                >
                  <OpenInFullIcon sx={{ padding: '2px' }} />
                </IconButton>
              )}
              <IconButton onClick={onClose} aria-label="close" size="small">
                <CloseIcon />
              </IconButton>
            </Box>
          </Box>
        ) : (
          title
        )}
      </DialogTitle>
      <DialogContent
        dividers={dividers}
        sx={[
          baseContentSx,
          ...(Array.isArray(contentSx) ? contentSx : [contentSx])
        ]}
        {...dialogContentProps}
      >
        {isExpanded ? (
          <Stack spacing={currentSpacing} sx={contentWrapperSx}>
            {children}
          </Stack>
        ) : (
          <Stack spacing={currentSpacing}>{children}</Stack>
        )}
      </DialogContent>
      {actions && (
        <DialogActions
          sx={{
            borderTop: actionsBorderTop
              ? theme => `1px solid ${theme.palette.divider}`
              : undefined,
            justifyContent: actionsJustifyContent
          }}
        >
          {actions}
        </DialogActions>
      )}
    </Dialog>
  )
}

export default ResponsiveDialog
