import type { Meta, StoryFn } from '@storybook/react'
import React, { useState } from 'react'
import { MessageText } from 'stream-chat-react'

import type { LockedAttachmentGalleryItem } from './types'

import LockedAttachment from '.'

const meta: Meta = {
  title: 'LockedAttachment',
  parameters: { layout: 'fullscreen' },
}
export default meta

const MatrixTable: React.FC<{ children: React.ReactNode }> = ({ children }) => (
  <div className="min-h-screen w-full bg-[#F9F7F4] p-12">
    <table className="border-separate border-spacing-4">
      <thead>
        <tr>
          <th className="w-8 pb-2" />
          <th className="pb-2 text-left text-xs font-medium text-black/40">
            Visitor
          </th>
          <th className="pb-2 text-left text-xs font-medium text-black/40">
            Creator
          </th>
        </tr>
      </thead>
      <tbody>{children}</tbody>
    </table>
  </div>
)

const MatrixTableRow: React.FC<{
  label: React.ReactNode
  received: React.ReactNode
  sent: React.ReactNode
}> = ({ label, received, sent }) => (
  <tr>
    <td className="whitespace-nowrap pr-4 align-top text-xs font-medium text-black/40">
      {label}
    </td>
    <td className="align-top">
      <MatrixTableCell isMine={false}>{received}</MatrixTableCell>
    </td>
    <td className="align-top">
      <MatrixTableCell isMine>{sent}</MatrixTableCell>
    </td>
  </tr>
)

/**
 * Deliberately renders WITHOUT any `.str-chat` ancestor or
 * `str-chat__message*` structure — the real Composer/preview surfaces this
 * card renders in outside a message thread. If a card looks wrong here, it's
 * leaning on ambient stream-chat-react CSS instead of its own explicit
 * styling.
 */
const MatrixTableCell: React.FC<{
  isMine: boolean
  children: React.ReactNode
}> = ({ children }) => <div>{children}</div>

export const Text: StoryFn = () => {
  const [isUnlocking, setUnlocking] = useState(false)

  // Matches what `CustomMessage` passes `MessageText` for a revealed paid
  // text attachment (`displayMessage`) — just enough of a `LocalMessage`
  // shape to render the real `str-chat__message-text` markup/CSS.
  const purchasedMessage = {
    text: "Here's the address, see you Thursday at 7!",
    type: 'regular',
  } as Parameters<typeof MessageText>[0]['message']

  return (
    <MatrixTable>
      <MatrixTableRow
        label="Draft"
        received={null}
        sent={
          <LockedAttachment
            isDraft
            contentType="text"
            renderedText={purchasedMessage?.text}
            amountText="AU$4.99"
            onDismiss={() => alert('Removed')}
          />
        }
      />
      <MatrixTableRow
        label="Preview"
        received={null}
        sent={
          <LockedAttachment
            isPreview
            contentType="text"
            placeholderAmountText="AU$0.00"
          />
        }
      />
      <MatrixTableRow
        label="Idle"
        received={
          <LockedAttachment
            isMine={false}
            contentType="text"
            amountText="AU$4.99"
            isUnlocking={isUnlocking}
            onUnlockClick={() => {
              setUnlocking(true)
              setTimeout(() => setUnlocking(false), 1500)
            }}
          />
        }
        sent={
          <LockedAttachment
            isMine
            contentType="text"
            amountText="AU$4.99"
            paymentStatus="pending"
          />
        }
      />
      <MatrixTableRow
        label="Unlocking"
        received={
          <LockedAttachment
            isMine={false}
            contentType="text"
            amountText="AU$4.99"
            isUnlocking
          />
        }
        sent={null}
      />
      <MatrixTableRow
        label="Purchased"
        received={
          <LockedAttachment
            isMine={false}
            contentType="text"
            amountText="AU$4.99"
            paymentStatus="paid"
            renderedText={<MessageText message={purchasedMessage} />}
          />
        }
        sent={
          <LockedAttachment
            isMine
            contentType="text"
            amountText="AU$4.99"
            paymentStatus="paid"
            renderedText={<MessageText message={purchasedMessage} />}
          />
        }
      />
    </MatrixTable>
  )
}

const VIDEO_THUMBNAIL_BLURRED = '/video-thumbnail-blurred.jpg'
const VIDEO_THUMBNAIL = '/video-thumbnail.jpg'
const VIDEO_SOURCE = '/video-source.mp4'

const AUDIO_THUMBNAIL_BLURRED = '/audio-thumbnail-blurred.jpg'
const AUDIO_THUMBNAIL = '/audio-thumbnail.jpg'
const AUDIO_SOURCE = '/audio-source.mp3'

const IMAGE_THUMBNAIL_BLURRED = '/image-thumbnail-blurred.jpg'
const IMAGE_THUMBNAIL = '/image-thumbnail.jpg'
const IMAGE_SOURCE = '/image-source.jpg'

const DOCUMENT_THUMBNAIL_BLURRED = '/document-thumbnail-blurred.jpg'
const DOCUMENT_THUMBNAIL = '/document-thumbnail.jpg'
const DOCUMENT_SOURCE = '/document-source.pdf'

const VARIANTS = [
  {
    label: 'Video',
    title: "Alicia's Workout Plan",
    mimeType: 'video/mp4',
    detail: '1:20',
    thumbnailUrl: VIDEO_THUMBNAIL_BLURRED,
    thumbnailUnlockedUrl: VIDEO_THUMBNAIL,
    sourceUrl: VIDEO_SOURCE,
  },
  {
    label: 'Audio',
    title: 'Morning Meditation',
    mimeType: 'audio/mpeg',
    detail: '4:35',
    thumbnailUrl: AUDIO_THUMBNAIL_BLURRED,
    thumbnailUnlockedUrl: AUDIO_THUMBNAIL,
    sourceUrl: AUDIO_SOURCE,
  },
  {
    label: 'Image',
    title: 'Picture of my cat',
    mimeType: 'image/jpeg',
    detail: '3.2 MB',
    thumbnailUrl: IMAGE_THUMBNAIL_BLURRED,
    thumbnailUnlockedUrl: IMAGE_THUMBNAIL,
    sourceUrl: IMAGE_SOURCE,
  },
  {
    label: 'Document',
    title: 'Strength Training Guide',
    mimeType: 'application/zip',
    detail: '14 files',
    thumbnailUrl: DOCUMENT_THUMBNAIL_BLURRED,
    thumbnailUnlockedUrl: DOCUMENT_THUMBNAIL,
    sourceUrl: DOCUMENT_SOURCE,
  },
  {
    label: 'Unknown',
    title: 'Unknown Attachment',
    mimeType: 'application/octet-stream',
    detail: '2.4 MB',
    thumbnailUrl: undefined,
    thumbnailUnlockedUrl: undefined,
    sourceUrl: DOCUMENT_SOURCE,
  },
]

/**
 * A mixed-media collection (a video + 3 photos) used by the Gallery stories
 * below. `LockedAttachment` accepts a `gallery` prop and renders a carousel
 * of these items when 2+ items are provided.
 */
const GALLERY_ITEMS: LockedAttachmentGalleryItem[] = [
  {
    mimeType: 'video/mp4',
    thumbnailUrl: VIDEO_THUMBNAIL,
    sourceUrl: VIDEO_SOURCE,
  },
  {
    mimeType: 'image/jpeg',
    thumbnailUrl: IMAGE_THUMBNAIL,
    sourceUrl: IMAGE_SOURCE,
  },
  {
    mimeType: 'application/pdf',
    thumbnailUrl: DOCUMENT_THUMBNAIL,
    sourceUrl: DOCUMENT_SOURCE,
  },
  {
    mimeType: 'audio/mpeg',
    thumbnailUrl: AUDIO_THUMBNAIL,
    sourceUrl: AUDIO_SOURCE,
  },
]

const GALLERY_DETAIL = '4 items'
const GALLERY_TITLE = 'Workout Guide'

const MediaMatrix: React.FC<{ variant: (typeof VARIANTS)[number] }> = ({
  variant,
}) => {
  const [isPaid, setPaid] = useState(false)
  const [isUnlocking, setUnlocking] = useState(false)
  const {
    title,
    mimeType,
    detail,
    thumbnailUrl,
    thumbnailUnlockedUrl,
    sourceUrl,
  } = variant

  const fetchSource = async () => ({
    sourceUrl,
    thumbnailUrl: thumbnailUnlockedUrl,
  })

  return (
    <MatrixTable>
      <MatrixTableRow
        label="Draft"
        received={null}
        sent={
          <LockedAttachment
            isDraft
            title={title}
            thumbnailUrl={thumbnailUrl}
            contentType="media"
            mimeType={mimeType}
            detail={detail}
            amountText="AU$9.99"
            onDismiss={() => alert('Dismissed')}
          />
        }
      />
      <MatrixTableRow
        label="Preview"
        received={null}
        sent={
          <LockedAttachment
            isPreview
            placeholderTitle="Attachment title"
            placeholderAmountText="AU$0.00"
            thumbnailUrl={thumbnailUrl}
            mimeType={mimeType}
            contentType="media"
            detail={detail}
          />
        }
      />
      <MatrixTableRow
        label="Idle"
        received={
          <LockedAttachment
            isMine={false}
            title={title}
            thumbnailUrl={thumbnailUrl}
            mimeType={mimeType}
            contentType="media"
            detail={detail}
            amountText="AU$9.99"
            paymentStatus={isPaid ? 'paid' : undefined}
            isUnlocking={isUnlocking}
            onUnlockClick={() => {
              setUnlocking(true)
              setTimeout(() => {
                setUnlocking(false)
                setPaid(true)
              }, 1500)
            }}
            onDownloadClick={() => alert('Download clicked')}
            onFetchSource={fetchSource}
          />
        }
        sent={
          <LockedAttachment
            isMine
            title={title}
            thumbnailUrl={thumbnailUrl}
            mimeType={mimeType}
            contentType="media"
            detail={detail}
            amountText="AU$9.99"
            onFetchSource={fetchSource}
          />
        }
      />
      <MatrixTableRow
        label="Unlocking"
        received={
          <LockedAttachment
            isMine={false}
            title={title}
            thumbnailUrl={thumbnailUrl}
            mimeType={mimeType}
            contentType="media"
            detail={detail}
            amountText="AU$9.99"
            isUnlocking
            onDownloadClick={() => alert('Download clicked')}
            onFetchSource={fetchSource}
          />
        }
        // Sender never unlocks their own message — no distinct state to show.
        sent={null}
      />
      <MatrixTableRow
        label="Purchased"
        received={
          <LockedAttachment
            isMine={false}
            title={title}
            thumbnailUrl={thumbnailUrl}
            mimeType={mimeType}
            contentType="media"
            detail={detail}
            amountText="AU$9.99"
            paymentStatus="paid"
            onUnlockClick={() => alert('Unlock clicked')}
            onDownloadClick={() => alert('Download clicked')}
            onFetchSource={fetchSource}
          />
        }
        sent={
          <LockedAttachment
            isMine
            title={title}
            thumbnailUrl={thumbnailUrl}
            mimeType={mimeType}
            contentType="media"
            detail={detail}
            amountText="AU$9.99"
            paymentStatus="paid"
            onFetchSource={fetchSource}
          />
        }
      />
    </MatrixTable>
  )
}

const variantByLabel = (label: string) =>
  VARIANTS.find((v) => v.label === label)!

export const Video: StoryFn = () => (
  <MediaMatrix variant={variantByLabel('Video')} />
)
// LockedAttachment (contentType="media", !isMine) autoplays the video preview once paid; even with
// our SMIL/CSS animation freeze the <video> element advances frames
// independently and produces a non-deterministic snapshot. Skip in Chromatic.
Video.parameters = { chromatic: { disableSnapshot: true } }

export const Audio: StoryFn = () => (
  <MediaMatrix variant={variantByLabel('Audio')} />
)

export const Image: StoryFn = () => (
  <MediaMatrix variant={variantByLabel('Image')} />
)

export const Document: StoryFn = () => (
  <MediaMatrix variant={variantByLabel('Document')} />
)

export const Unknown: StoryFn = () => (
  <MediaMatrix variant={variantByLabel('Unknown')} />
)

export const Gallery: StoryFn = () => {
  const [isPaid, setPaid] = useState(false)
  const [isUnlocking, setUnlocking] = useState(false)

  return (
    <MatrixTable>
      <MatrixTableRow
        label="Draft"
        received={null}
        sent={
          <LockedAttachment
            isDraft
            contentType="media"
            title={GALLERY_TITLE}
            detail={GALLERY_DETAIL}
            amountText="AU$50.00"
            gallery={GALLERY_ITEMS}
            onDismiss={() => alert('Dismissed gallery')}
            onEditClick={() => alert('Edit gallery')}
          />
        }
      />
      <MatrixTableRow
        label="Preview"
        received={null}
        sent={
          <LockedAttachment
            isPreview
            contentType="media"
            placeholderTitle="Attachment title"
            detail={GALLERY_DETAIL}
            placeholderAmountText="AU$0.00"
            gallery={GALLERY_ITEMS}
          />
        }
      />
      <MatrixTableRow
        label="Idle"
        received={
          <LockedAttachment
            isMine={false}
            contentType="media"
            title={GALLERY_TITLE}
            detail={GALLERY_DETAIL}
            amountText="AU$50.00"
            gallery={GALLERY_ITEMS}
            paymentStatus={isPaid ? 'paid' : undefined}
            isUnlocking={isUnlocking}
            onUnlockClick={() => {
              setUnlocking(true)
              setTimeout(() => {
                setUnlocking(false)
                setPaid(true)
              }, 1500)
            }}
            onDownloadClick={() => alert('Download gallery')}
          />
        }
        sent={
          <LockedAttachment
            isMine
            contentType="media"
            title={GALLERY_TITLE}
            detail={GALLERY_DETAIL}
            amountText="AU$50.00"
            gallery={GALLERY_ITEMS}
          />
        }
      />
      <MatrixTableRow
        label="Unlocking"
        received={
          <LockedAttachment
            isMine={false}
            contentType="media"
            title={GALLERY_TITLE}
            detail={GALLERY_DETAIL}
            amountText="AU$50.00"
            gallery={GALLERY_ITEMS}
            isUnlocking
            onDownloadClick={() => alert('Download gallery')}
          />
        }
        // Sender never unlocks their own message — no distinct state to show.
        sent={null}
      />
      <MatrixTableRow
        label="Purchased"
        received={
          <LockedAttachment
            isMine={false}
            contentType="media"
            title={GALLERY_TITLE}
            detail={GALLERY_DETAIL}
            amountText="AU$50.00"
            paymentStatus="paid"
            gallery={GALLERY_ITEMS}
            onUnlockClick={() => alert('Unlock clicked')}
            onDownloadClick={() => alert('Download gallery')}
          />
        }
        sent={
          <LockedAttachment
            isMine
            contentType="media"
            title={GALLERY_TITLE}
            detail={GALLERY_DETAIL}
            amountText="AU$50.00"
            paymentStatus="paid"
            gallery={GALLERY_ITEMS}
          />
        }
      />
    </MatrixTable>
  )
}
