/**
 * Tests unitaires pour la logique de détermination des champs readonly
 */

import {
  getReadonlyFieldsForTask,
  shouldPreserveFieldDuringSync,
  buildSyncUpdateData,
} from '../readonly-fields';

describe('getReadonlyFieldsForTask', () => {
  describe('Jira', () => {
    it('devrait retourner description et dueDate comme readonly', () => {
      const result = getReadonlyFieldsForTask('jira', 'todo');
      expect(result).toContain('description');
      expect(result).toContain('dueDate');
      expect(result).toContain('status');
      expect(result).not.toContain('title');
      expect(result).not.toContain('priority');
    });

    it('ne devrait pas retourner status comme readonly si archived', () => {
      const result = getReadonlyFieldsForTask('jira', 'archived');
      expect(result).toContain('description');
      expect(result).toContain('dueDate');
      expect(result).not.toContain('status');
    });

    it('devrait permettre title et priority comme modifiables', () => {
      const result = getReadonlyFieldsForTask('jira', 'todo');
      expect(result).not.toContain('title');
      expect(result).not.toContain('priority');
    });
  });

  describe('TFS', () => {
    it('devrait retourner tous les champs comme readonly', () => {
      const result = getReadonlyFieldsForTask('tfs', 'todo');
      expect(result).toContain('title');
      expect(result).toContain('description');
      expect(result).toContain('status');
      expect(result).toContain('priority');
      expect(result).toContain('dueDate');
    });

    it('devrait retourner tous les champs même si archived', () => {
      const result = getReadonlyFieldsForTask('tfs', 'archived');
      expect(result).toContain('title');
      expect(result).toContain('status');
    });
  });

  describe('Manual', () => {
    it('ne devrait retourner aucun champ readonly', () => {
      const result = getReadonlyFieldsForTask('manual', 'todo');
      expect(result).toHaveLength(0);
    });
  });
});

describe('shouldPreserveFieldDuringSync', () => {
  describe('Jira', () => {
    it('devrait préserver title si modifié localement', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'title',
        'Titre local modifié',
        'Titre Jira original'
      );
      expect(result).toBe(true);
    });

    it('ne devrait pas préserver title si identique', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'title',
        'Même titre',
        'Même titre'
      );
      expect(result).toBe(false);
    });

    it('devrait préserver priority si modifié localement', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'priority',
        'high',
        'medium'
      );
      expect(result).toBe(true);
    });

    it('devrait préserver status si archived', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'status',
        'archived',
        'done',
        'archived'
      );
      expect(result).toBe(true);
    });

    it('ne devrait pas préserver status si pas archived', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'status',
        'todo',
        'in_progress',
        'todo'
      );
      expect(result).toBe(false);
    });

    it('ne devrait jamais préserver description', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'description',
        'Description locale',
        'Description Jira'
      );
      expect(result).toBe(false);
    });

    it('ne devrait jamais préserver dueDate', () => {
      const result = shouldPreserveFieldDuringSync(
        'jira',
        'dueDate',
        new Date('2024-01-01'),
        new Date('2024-01-02')
      );
      expect(result).toBe(false);
    });
  });

  describe('TFS', () => {
    it('ne devrait jamais préserver aucun champ', () => {
      expect(
        shouldPreserveFieldDuringSync('tfs', 'title', 'Local', 'TFS')
      ).toBe(false);
      expect(
        shouldPreserveFieldDuringSync('tfs', 'description', 'Local', 'TFS')
      ).toBe(false);
      expect(
        shouldPreserveFieldDuringSync('tfs', 'status', 'todo', 'done')
      ).toBe(false);
      expect(
        shouldPreserveFieldDuringSync('tfs', 'priority', 'high', 'medium')
      ).toBe(false);
      expect(
        shouldPreserveFieldDuringSync(
          'tfs',
          'dueDate',
          new Date('2024-01-01'),
          new Date('2024-01-02')
        )
      ).toBe(false);
    });
  });
});

describe('buildSyncUpdateData', () => {
  describe('Jira', () => {
    const existingTask = {
      title: 'Tâche locale',
      description: 'Description locale',
      status: 'todo',
      priority: 'high',
      dueDate: new Date('2024-01-01'),
    };

    const syncData = {
      title: 'Tâche Jira',
      description: 'Description Jira',
      status: 'in_progress',
      priority: 'medium',
      dueDate: new Date('2024-01-02'),
    };

    it('devrait préserver title si modifié localement', () => {
      const result = buildSyncUpdateData('jira', existingTask, syncData);
      expect(result.title).toBe('Tâche locale');
    });

    it('devrait préserver priority si modifié localement', () => {
      const result = buildSyncUpdateData('jira', existingTask, syncData);
      expect(result.priority).toBe('high');
    });

    it('devrait écraser description', () => {
      const result = buildSyncUpdateData('jira', existingTask, syncData);
      expect(result.description).toBe('Description Jira');
    });

    it('devrait écraser dueDate', () => {
      const result = buildSyncUpdateData('jira', existingTask, syncData);
      expect(result.dueDate).toEqual(new Date('2024-01-02'));
    });

    it('devrait écraser status si pas archived', () => {
      const result = buildSyncUpdateData('jira', existingTask, syncData);
      expect(result.status).toBe('in_progress');
    });

    it('devrait préserver status si archived', () => {
      const archivedTask = { ...existingTask, status: 'archived' };
      const result = buildSyncUpdateData('jira', archivedTask, syncData);
      expect(result.status).toBe('archived');
    });

    it('devrait utiliser syncData si title identique', () => {
      const sameTitleTask = { ...existingTask, title: 'Tâche Jira' };
      const result = buildSyncUpdateData('jira', sameTitleTask, syncData);
      expect(result.title).toBe('Tâche Jira');
    });
  });

  describe('TFS', () => {
    const existingTask = {
      title: 'Tâche locale',
      description: 'Description locale',
      status: 'todo',
      priority: 'high',
      dueDate: new Date('2024-01-01'),
    };

    const syncData = {
      title: 'PR: Tâche TFS',
      description: 'Description TFS',
      status: 'done',
      priority: 'medium',
      dueDate: null,
    };

    it('devrait écraser tous les champs', () => {
      const result = buildSyncUpdateData('tfs', existingTask, syncData);
      expect(result.title).toBe('PR: Tâche TFS');
      expect(result.description).toBe('Description TFS');
      expect(result.status).toBe('done');
      expect(result.priority).toBe('medium');
      expect(result.dueDate).toBeNull();
    });

    it('devrait écraser même si valeurs différentes localement', () => {
      const modifiedTask = {
        ...existingTask,
        title: 'Titre modifié localement',
        priority: 'low',
      };
      const result = buildSyncUpdateData('tfs', modifiedTask, syncData);
      expect(result.title).toBe('PR: Tâche TFS');
      expect(result.priority).toBe('medium');
    });
  });
});
