import { describe, it, expect, vi, beforeEach } from 'vitest'
import React from 'react'
import { render, screen, fireEvent, waitFor, act } from '@testing-library/react-native'
import { DataDeletionModal } from '@/src/shared/components/DataDeletionModal'

describe('DataDeletionModal', () => {
  const defaultProps = {
    visible: true,
    onDelete: vi.fn().mockResolvedValue(undefined),
    onCancel: vi.fn(),
  }

  beforeEach(() => {
    vi.clearAllMocks()
  })

  it('renders when visible is true', () => {
    render(<DataDeletionModal {...defaultProps} />)
    // Title key from i18n mock
    expect(screen.getByText('dataDeletion.title')).toBeTruthy()
  })

  it('renders warning icon', () => {
    render(<DataDeletionModal {...defaultProps} />)
    expect(screen.getByTestId('icon-warning')).toBeTruthy()
  })

  it('renders description and note text', () => {
    render(<DataDeletionModal {...defaultProps} />)
    expect(screen.getByText('dataDeletion.description')).toBeTruthy()
    expect(screen.getByText('dataDeletion.note')).toBeTruthy()
  })

  it('renders delete and cancel buttons', () => {
    render(<DataDeletionModal {...defaultProps} />)
    expect(screen.getByText('dataDeletion.deleteButton')).toBeTruthy()
    expect(screen.getByText('dataDeletion.cancelButton')).toBeTruthy()
  })

  it('calls onCancel when cancel button is pressed', () => {
    render(<DataDeletionModal {...defaultProps} />)
    fireEvent.press(screen.getByText('dataDeletion.cancelButton'))
    expect(defaultProps.onCancel).toHaveBeenCalledTimes(1)
  })

  it('calls onDelete when delete button is pressed', async () => {
    render(<DataDeletionModal {...defaultProps} />)
    await act(async () => {
      fireEvent.press(screen.getByText('dataDeletion.deleteButton'))
    })
    expect(defaultProps.onDelete).toHaveBeenCalledTimes(1)
  })

  it('shows loading text while deleting', async () => {
    let resolveDelete: () => void
    const slowDelete = new Promise<void>((resolve) => {
      resolveDelete = resolve
    })
    const onDelete = vi.fn(() => slowDelete)

    render(<DataDeletionModal visible={true} onDelete={onDelete} onCancel={vi.fn()} />)

    // Start delete
    await act(async () => {
      fireEvent.press(screen.getByText('dataDeletion.deleteButton'))
    })

    // Should show 'Deleting...' while in progress
    expect(screen.getByText('Deleting...')).toBeTruthy()

    // Complete the delete
    await act(async () => {
      resolveDelete!()
    })
  })

  it('does not render content when visible is false', () => {
    render(<DataDeletionModal {...defaultProps} visible={false} />)
    // Modal with visible=false won't render its children
    expect(screen.queryByText('dataDeletion.title')).toBeNull()
  })

  it('full modal structure snapshot', () => {
    const { toJSON } = render(<DataDeletionModal {...defaultProps} />)
    expect(toJSON()).toMatchSnapshot()
  })

  it('delete button shows disabled state while deleting', async () => {
    let resolveDelete: () => void
    const slowDelete = new Promise<void>((resolve) => {
      resolveDelete = resolve
    })
    const onDelete = vi.fn(() => slowDelete)

    const { toJSON } = render(
      <DataDeletionModal visible={true} onDelete={onDelete} onCancel={vi.fn()} />
    )

    await act(async () => {
      fireEvent.press(screen.getByText('dataDeletion.deleteButton'))
    })

    // While deleting, the button text changes to loading state
    expect(screen.getByText('Deleting...')).toBeTruthy()

    // Verify the tree has the disabled styling applied (opacity: 0.6)
    const tree = toJSON()
    const treeStr = JSON.stringify(tree)
    expect(treeStr).toContain('"opacity":0.6')

    await act(async () => {
      resolveDelete!()
    })
  })
})
