/**
 * Tests pour les utilitaires de permissions de playlist
 * T0485: Create Playlist Permission Frontend Checks
 */

import { describe, it, expect } from 'vitest';
import {
  canEdit,
  canDelete,
  canAddTracks,
  canRemoveTracks,
  canManageCollaborators,
  canRead,
} from './permissions';
import type { Playlist } from '../types';
import type { PlaylistCollaborator } from '../services/playlistService';

const mockPlaylist: Playlist = {
  id: 1,
  user_id: 1,
  title: 'Test Playlist',
  description: 'Test Description',
  is_public: false,
  cover_url: null,
  track_count: 0,
  created_at: '2024-01-01T00:00:00Z',
  updated_at: '2024-01-01T00:00:00Z',
  tracks: [],
};

const mockPublicPlaylist: Playlist = {
  ...mockPlaylist,
  id: 2,
  is_public: true,
};

const mockCollaboratorRead: PlaylistCollaborator = {
  id: 1,
  playlist_id: 1,
  user_id: 2,
  permission: 'read',
  created_at: '2024-01-01T00:00:00Z',
  updated_at: '2024-01-01T00:00:00Z',
};

const mockCollaboratorWrite: PlaylistCollaborator = {
  id: 2,
  playlist_id: 1,
  user_id: 3,
  permission: 'write',
  created_at: '2024-01-01T00:00:00Z',
  updated_at: '2024-01-01T00:00:00Z',
};

const mockCollaboratorAdmin: PlaylistCollaborator = {
  id: 3,
  playlist_id: 1,
  user_id: 4,
  permission: 'admin',
  created_at: '2024-01-01T00:00:00Z',
  updated_at: '2024-01-01T00:00:00Z',
};

describe('canEdit', () => {
  it('should return true for owner', () => {
    expect(canEdit(mockPlaylist, 1)).toBe(true);
  });

  it('should return true for collaborator with write permission', () => {
    expect(canEdit(mockPlaylist, 3, [mockCollaboratorWrite])).toBe(true);
  });

  it('should return true for collaborator with admin permission', () => {
    expect(canEdit(mockPlaylist, 4, [mockCollaboratorAdmin])).toBe(true);
  });

  it('should return false for collaborator with read permission', () => {
    expect(canEdit(mockPlaylist, 2, [mockCollaboratorRead])).toBe(false);
  });

  it('should return false for non-collaborator', () => {
    expect(canEdit(mockPlaylist, 5)).toBe(false);
  });

  it('should return false when userId is null', () => {
    expect(canEdit(mockPlaylist, null)).toBe(false);
  });

  it('should return false when userId is undefined', () => {
    expect(canEdit(mockPlaylist, undefined)).toBe(false);
  });
});

describe('canDelete', () => {
  it('should return true for owner', () => {
    expect(canDelete(mockPlaylist, 1)).toBe(true);
  });

  it('should return false for collaborator with write permission', () => {
    expect(canDelete(mockPlaylist, 3)).toBe(false);
  });

  it('should return false for collaborator with admin permission', () => {
    expect(canDelete(mockPlaylist, 4)).toBe(false);
  });

  it('should return false for non-owner', () => {
    expect(canDelete(mockPlaylist, 2)).toBe(false);
  });

  it('should return false when userId is null', () => {
    expect(canDelete(mockPlaylist, null)).toBe(false);
  });
});

describe('canAddTracks', () => {
  it('should return true for owner', () => {
    expect(canAddTracks(mockPlaylist, 1)).toBe(true);
  });

  it('should return true for collaborator with write permission', () => {
    expect(canAddTracks(mockPlaylist, 3, [mockCollaboratorWrite])).toBe(true);
  });

  it('should return true for collaborator with admin permission', () => {
    expect(canAddTracks(mockPlaylist, 4, [mockCollaboratorAdmin])).toBe(true);
  });

  it('should return false for collaborator with read permission', () => {
    expect(canAddTracks(mockPlaylist, 2, [mockCollaboratorRead])).toBe(false);
  });

  it('should return false for non-collaborator', () => {
    expect(canAddTracks(mockPlaylist, 5)).toBe(false);
  });

  it('should return false when userId is null', () => {
    expect(canAddTracks(mockPlaylist, null)).toBe(false);
  });
});

describe('canRemoveTracks', () => {
  it('should return true for owner', () => {
    expect(canRemoveTracks(mockPlaylist, 1)).toBe(true);
  });

  it('should return true for collaborator with write permission', () => {
    expect(canRemoveTracks(mockPlaylist, 3, [mockCollaboratorWrite])).toBe(
      true,
    );
  });

  it('should return true for collaborator with admin permission', () => {
    expect(canRemoveTracks(mockPlaylist, 4, [mockCollaboratorAdmin])).toBe(
      true,
    );
  });

  it('should return false for collaborator with read permission', () => {
    expect(canRemoveTracks(mockPlaylist, 2, [mockCollaboratorRead])).toBe(
      false,
    );
  });

  it('should return false for non-collaborator', () => {
    expect(canRemoveTracks(mockPlaylist, 5)).toBe(false);
  });

  it('should return false when userId is null', () => {
    expect(canRemoveTracks(mockPlaylist, null)).toBe(false);
  });
});

describe('canManageCollaborators', () => {
  it('should return true for owner', () => {
    expect(canManageCollaborators(mockPlaylist, 1)).toBe(true);
  });

  it('should return false for collaborator with write permission', () => {
    expect(canManageCollaborators(mockPlaylist, 3)).toBe(false);
  });

  it('should return false for collaborator with admin permission', () => {
    expect(canManageCollaborators(mockPlaylist, 4)).toBe(false);
  });

  it('should return false for non-owner', () => {
    expect(canManageCollaborators(mockPlaylist, 2)).toBe(false);
  });

  it('should return false when userId is null', () => {
    expect(canManageCollaborators(mockPlaylist, null)).toBe(false);
  });
});

describe('canRead', () => {
  it('should return true for owner', () => {
    expect(canRead(mockPlaylist, 1)).toBe(true);
  });

  it('should return true for public playlist', () => {
    expect(canRead(mockPublicPlaylist, 5)).toBe(true);
  });

  it('should return true for collaborator with read permission', () => {
    expect(canRead(mockPlaylist, 2, [mockCollaboratorRead])).toBe(true);
  });

  it('should return true for collaborator with write permission', () => {
    expect(canRead(mockPlaylist, 3, [mockCollaboratorWrite])).toBe(true);
  });

  it('should return true for collaborator with admin permission', () => {
    expect(canRead(mockPlaylist, 4, [mockCollaboratorAdmin])).toBe(true);
  });

  it('should return false for non-collaborator on private playlist', () => {
    expect(canRead(mockPlaylist, 5)).toBe(false);
  });

  it('should return false when userId is null on private playlist', () => {
    expect(canRead(mockPlaylist, null)).toBe(false);
  });

  it('should return true when userId is null on public playlist', () => {
    expect(canRead(mockPublicPlaylist, null)).toBe(true);
  });
});
