import React from 'react';
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
import { ShareDialog } from '@/components/dms/ShareDialog';
import type { DmsFile } from '@/api/dms';

const mockFile: DmsFile = {
  id: 'file1',
  folder_id: null,
  name: 'Vertrag.pdf',
  mime_type: 'application/pdf',
  size: 102400,
  storage_path: '/storage/file1',
  deleted_at: null,
  created_by: 'u1',
};

vi.mock('@/api/permissions', () => ({
  fetchFilePermissions: vi.fn().mockResolvedValue([
    { id: 'p1', file_id: 'file1', user_id: 'u2', group_id: null, permission: 'read', user_name: 'Max Mustermann', created_at: '2026-01-01T00:00:00Z' },
  ]),
  grantPermission: vi.fn(),
  revokePermission: vi.fn().mockResolvedValue(undefined),
  createShareLink: vi.fn().mockResolvedValue({
    id: 'sl1', file_id: 'file1', token: 'abc123',
    url: 'https://example.com/share/abc123',
    password_protected: false, expires_at: null, created_at: '2026-01-01T00:00:00Z',
  }),
  revokeShareLink: vi.fn().mockResolvedValue(undefined),
}));

vi.mock('@/api/dms', () => ({
  shareFile: vi.fn().mockResolvedValue({ id: 's1', file_id: 'file1', user_id: 'u3', permission: 'read' }),
  removeShare: vi.fn().mockResolvedValue(undefined),
}));

vi.mock('@/components/ui/Toast', () => ({
  useToast: () => ({ success: vi.fn(), error: vi.fn(), info: vi.fn(), warning: vi.fn() }),
}));

import { fetchFilePermissions, createShareLink } from '@/api/permissions';
import { shareFile } from '@/api/dms';

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

describe('ShareDialog', () => {
  it('renders dialog when open with file', async () => {
    render(<ShareDialog open={true} file={mockFile} onClose={vi.fn()} onShared={vi.fn()} />);
    expect(screen.getByRole('dialog')).toBeInTheDocument();
  });

  it('does not render when file is null', () => {
    render(<ShareDialog open={false} file={null} onClose={vi.fn()} onShared={vi.fn()} />);
    expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
  });

  it('renders share add section with user/group select', async () => {
    render(<ShareDialog open={true} file={mockFile} onClose={vi.fn()} onShared={vi.fn()} />);
    expect(screen.getByTestId('share-add-section')).toBeInTheDocument();
    expect(screen.getByText('Benutzer oder Gruppe')).toBeInTheDocument();
  });

  it('renders permissions list after loading', async () => {
    render(<ShareDialog open={true} file={mockFile} onClose={vi.fn()} onShared={vi.fn()} />);
    await waitFor(() => {
      expect(fetchFilePermissions).toHaveBeenCalledWith('file1');
    });
    await waitFor(() => {
      expect(screen.getByText('Max Mustermann')).toBeInTheDocument();
    });
  });

  it('renders public share link section', async () => {
    render(<ShareDialog open={true} file={mockFile} onClose={vi.fn()} onShared={vi.fn()} />);
    expect(screen.getByTestId('share-link-section')).toBeInTheDocument();
  });

  it('creates share link when clicking create button', async () => {
    render(<ShareDialog open={true} file={mockFile} onClose={vi.fn()} onShared={vi.fn()} />);
    const createBtn = screen.getByRole('button', { name: 'Link erstellen' });
    fireEvent.click(createBtn);
    await waitFor(() => {
      expect(createShareLink).toHaveBeenCalledWith('file1', {});
    });
    await waitFor(() => {
      expect(screen.getByTestId('share-links-list')).toBeInTheDocument();
    });
  });

  it('shares file with user when add share is clicked', async () => {
    render(<ShareDialog open={true} file={mockFile} onClose={vi.fn()} onShared={vi.fn()} />);
    const userIdInput = screen.getByLabelText('Benutzer-ID');
    fireEvent.change(userIdInput, { target: { value: 'u5' } });
    const addBtn = screen.getByRole('button', { name: 'Freigabe hinzufuegen' });
    fireEvent.click(addBtn);
    await waitFor(() => {
      expect(shareFile).toHaveBeenCalledWith('file1', { user_id: 'u5', permission: 'read' });
    });
  });
});
