import React, { useState } from 'react';
import toast from 'react-hot-toast';
import styled from 'styled-components';
import { HiDocument, HiDownload, HiEye, HiPhotograph } from 'react-icons/hi';
import { useLocale } from '@/app/providers/LocaleProvider';
import { IconButton } from '@/shared/components/ui';
import type { TicketAttachment } from '@/features/tickets/types/ticket.types';
import { formatAttachmentSize, fileExtension } from '@/shared/utils/filePreview';
import {
  isImageAttachment,
  isPdfAttachment,
} from '@/shared/utils/attachmentType';
import {
  downloadAttachmentFile,
  openAttachmentInNewTab,
} from '@/shared/utils/fetchAttachment';
import { resolveAttachmentPreviewUrl } from '@/shared/utils/attachmentUrl';
import { ImageLightbox } from '@/shared/components/ui/FileUpload/ImageLightbox';

const Wrap = styled.div`
  display: flex;
  flex-wrap: wrap;
  gap: ${({ theme }) => theme.spacing[3]};
  width: 100%;
  min-width: 0;
  margin-top: ${({ theme }) => theme.spacing[3]};
`;

const AttachmentCard = styled.div`
  display: flex;
  flex-direction: column;
  gap: ${({ theme }) => theme.spacing[2]};
  width: min(100%, 240px);
  min-width: 0;
`;

const PreviewShell = styled.div<{ $accentColor?: string }>`
  position: relative;
  width: 100%;
  border-radius: ${({ theme }) => theme.borderRadius.lg};
  overflow: hidden;
  background: ${({ theme }) => theme.colors.surface};
  border: 1px solid
    ${({ theme, $accentColor }) =>
      $accentColor
        ? `color-mix(in srgb, ${$accentColor} 22%, ${theme.colors.borderSoft})`
        : theme.colors.borderSoft};
  box-shadow: ${({ theme }) => theme.shadows.sm};
`;

const PreviewStatic = styled.div<{ $accentColor?: string }>`
  display: block;
  width: 100%;
  aspect-ratio: 4 / 3;
  min-height: 140px;
  max-height: 220px;
  background: ${({ theme, $accentColor }) =>
    $accentColor
      ? `color-mix(in srgb, ${$accentColor} 10%, ${theme.colors.surfaceInset})`
      : theme.colors.surfaceInset};
`;

const PreviewFrame = styled.button<{ $accentColor?: string }>`
  display: block;
  width: 100%;
  padding: 0;
  border: none;
  cursor: pointer;
  background: ${({ theme, $accentColor }) =>
    $accentColor
      ? `color-mix(in srgb, ${$accentColor} 10%, ${theme.colors.surfaceInset})`
      : theme.colors.surfaceInset};

  &:focus-visible {
    outline: 2px solid ${({ theme }) => theme.colors.primary};
    outline-offset: -2px;
  }
`;

const PreviewImage = styled.img`
  display: block;
  width: 100%;
  height: auto;
  max-height: 320px;
  object-fit: contain;
`;

const FilePreview = styled.div<{ $accentColor?: string; $pdf?: boolean }>`
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: ${({ theme }) => theme.spacing[2]};
  color: ${({ theme, $accentColor, $pdf }) =>
    $pdf ? theme.colors.error : ($accentColor ?? theme.colors.primary)};
  background: ${({ theme, $accentColor, $pdf }) =>
    $pdf
      ? theme.colors.errorLight
      : $accentColor
        ? `color-mix(in srgb, ${$accentColor} 12%, ${theme.colors.surfaceInset})`
        : theme.colors.primaryLight};

  svg {
    width: 48px;
    height: 48px;
  }
`;

const PreviewExt = styled.span`
  font-size: ${({ theme }) => theme.typography.fontSize.xs};
  font-weight: ${({ theme }) => theme.typography.fontWeight.semibold};
  letter-spacing: ${({ theme }) => theme.typography.letterSpacing.wide};
  text-transform: uppercase;
  opacity: 0.85;
`;

const ActionBar = styled.div`
  position: absolute;
  top: ${({ theme }) => theme.spacing[2]};
  inset-inline-end: ${({ theme }) => theme.spacing[2]};
  display: inline-flex;
  align-items: center;
  gap: ${({ theme }) => theme.spacing[1]};
  padding: ${({ theme }) => theme.spacing[1]};
  border-radius: ${({ theme }) => theme.borderRadius.md};
  background: color-mix(in srgb, ${({ theme }) => theme.colors.surface} 92%, transparent);
  border: 1px solid ${({ theme }) => theme.colors.borderSoft};
  box-shadow: ${({ theme }) => theme.shadows.sm};
  backdrop-filter: blur(6px);
`;

const FileCaption = styled.div`
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
  padding-inline: ${({ theme }) => theme.spacing[1]};
`;

const FileName = styled.div`
  font-size: ${({ theme }) => theme.typography.fontSize.sm};
  font-weight: ${({ theme }) => theme.typography.fontWeight.medium};
  color: ${({ theme }) => theme.colors.text.primary};
  line-height: ${({ theme }) => theme.typography.lineHeight.normal};
  word-break: break-word;
  overflow-wrap: anywhere;
  text-align: start;
`;

const FileDetails = styled.div`
  font-size: ${({ theme }) => theme.typography.fontSize.xs};
  color: ${({ theme }) => theme.colors.text.tertiary};
  text-align: start;
`;

interface MessageAttachmentsProps {
  attachments: TicketAttachment[];
  /** Participant accent for borders and file icon tint */
  accentColor?: string;
  /** @deprecated Use accentColor — kept for backward compatibility */
  inverted?: boolean;
}

export const MessageAttachments: React.FC<MessageAttachmentsProps> = ({
  attachments,
  accentColor,
}) => {
  const { t } = useLocale();
  const [lightbox, setLightbox] = useState<{ src: string; alt: string } | null>(null);
  const [brokenImages, setBrokenImages] = useState<Record<string, boolean>>({});
  const [pendingAction, setPendingAction] = useState<string | null>(null);

  const runAttachmentAction = async (
    actionKey: string,
    action: () => Promise<void>,
  ): Promise<void> => {
    if (pendingAction) {
      return;
    }

    setPendingAction(actionKey);
    try {
      await action();
    } catch (error) {
      const message = error instanceof Error ? error.message : 'Failed to open attachment';
      toast.error(message);
    } finally {
      setPendingAction(null);
    }
  };

  if (attachments.length === 0) {
    return null;
  }

  return (
    <Wrap>
      {attachments.map((attachment) => {
        const previewSrc = resolveAttachmentPreviewUrl(attachment);
        const pdf = isPdfAttachment(attachment);
        const isImage = isImageAttachment(attachment) && !brokenImages[attachment.id];
        const viewLabel = t('common:actions.view');
        const downloadLabel = t('common:actions.download');
        const ext = fileExtension(attachment.file_name).toUpperCase();

        const openImagePreview = () => {
          setLightbox({ src: previewSrc, alt: attachment.file_name });
        };

        return (
          <AttachmentCard key={attachment.id}>
            <PreviewShell $accentColor={accentColor}>
              {isImage ? (
                <PreviewFrame
                  type="button"
                  $accentColor={accentColor}
                  aria-hidden
                  tabIndex={-1}
                  onClick={openImagePreview}
                >
                  <PreviewImage
                    src={previewSrc}
                    alt=""
                    loading="lazy"
                    onError={() =>
                      setBrokenImages((current) => ({ ...current, [attachment.id]: true }))
                    }
                  />
                </PreviewFrame>
              ) : (
                <PreviewStatic $accentColor={accentColor} aria-hidden>
                  <FilePreview $accentColor={accentColor} $pdf={pdf}>
                    {pdf ? <HiDocument /> : isImageAttachment(attachment) ? <HiPhotograph /> : <HiDocument />}
                    <PreviewExt>{ext}</PreviewExt>
                  </FilePreview>
                </PreviewStatic>
              )}

              <ActionBar>
                {isImage ? (
                  <IconButton
                    type="button"
                    size="sm"
                    tone="primary"
                    label={`${viewLabel}: ${attachment.file_name}`}
                    onClick={openImagePreview}
                  >
                    <HiEye aria-hidden />
                  </IconButton>
                ) : (
                  <IconButton
                    type="button"
                    size="sm"
                    tone="primary"
                    label={`${viewLabel}: ${attachment.file_name}`}
                    title={viewLabel}
                    disabled={pendingAction !== null}
                    onClick={() =>
                      runAttachmentAction(`${attachment.id}:view`, () =>
                        openAttachmentInNewTab(attachment, { inline: true }),
                      )
                    }
                  >
                    <HiEye aria-hidden />
                  </IconButton>
                )}
                <IconButton
                  type="button"
                  size="sm"
                  tone="primary"
                  label={`${downloadLabel}: ${attachment.file_name}`}
                  title={downloadLabel}
                  disabled={pendingAction !== null}
                  onClick={() =>
                    runAttachmentAction(`${attachment.id}:download`, () =>
                      downloadAttachmentFile(attachment),
                    )
                  }
                >
                  <HiDownload aria-hidden />
                </IconButton>
              </ActionBar>
            </PreviewShell>

            <FileCaption>
              <FileName>{attachment.file_name}</FileName>
              <FileDetails>
                {formatAttachmentSize(attachment.file_size, attachment.formatted_size, t)} · {ext}
              </FileDetails>
            </FileCaption>
          </AttachmentCard>
        );
      })}

      {lightbox && (
        <ImageLightbox
          src={lightbox.src}
          alt={lightbox.alt}
          onClose={() => setLightbox(null)}
        />
      )}
    </Wrap>
  );
};
