/**
 * Détermine quels champs sont en lecture seule pour une tâche synchronisée
 * Cette logique centralisée évite la duplication et facilite la maintenance
 */

import { TaskSource, TaskStatus } from '@/lib/types';

/**
 * Détermine les champs en lecture seule selon la source de synchronisation
 * @param source - Source de la tâche (jira, tfs, manual)
 * @param status - Statut actuel de la tâche (pour les règles spécifiques comme archived)
 * @returns Liste des noms de champs en lecture seule
 */
export function getReadonlyFieldsForTask(
  source: TaskSource,
  status?: TaskStatus
): string[] {
  const readonlyFields: string[] = [];

  if (source === 'jira') {
    // description: toujours écrasé par Jira → non modifiable
    readonlyFields.push('description');
    // dueDate: toujours écrasé par Jira → non modifiable
    readonlyFields.push('dueDate');
    // status: écrasé par Jira SAUF si archived (car archived est préservé localement)
    if (status !== 'archived') {
      readonlyFields.push('status');
    }
    // title et priority: peuvent être préservés si modifiés localement → modifiables
  } else if (source === 'tfs') {
    // Pour TFS, tous les champs synchronisés sont écrasés → non modifiables
    readonlyFields.push('title');
    readonlyFields.push('description');
    readonlyFields.push('status');
    readonlyFields.push('priority');
    readonlyFields.push('dueDate');
  }
  // Pour 'manual', aucun champ n'est readonly

  return readonlyFields;
}

/**
 * Détermine si un champ doit être préservé lors de la synchronisation
 * Cette fonction centralise la logique métier de préservation des champs
 * @param source - Source de la tâche (jira, tfs, manual)
 * @param field - Nom du champ à vérifier
 * @param existingValue - Valeur actuelle dans la base de données
 * @param syncValue - Valeur venant de la source externe (Jira/TFS)
 * @param currentStatus - Statut actuel de la tâche (pour les règles spécifiques)
 * @returns true si le champ doit être préservé (pas écrasé), false sinon
 */
export function shouldPreserveFieldDuringSync(
  source: TaskSource,
  field: 'title' | 'description' | 'status' | 'priority' | 'dueDate',
  existingValue: unknown,
  syncValue: unknown,
  currentStatus?: TaskStatus
): boolean {
  if (source === 'jira') {
    // Pour Jira, certains champs peuvent être préservés s'ils ont été modifiés localement
    if (field === 'title' || field === 'priority') {
      // Préserver si la valeur locale est différente de celle de Jira (modifié localement)
      return existingValue !== syncValue;
    }
    if (field === 'status') {
      // Préserver le statut archived local - ne jamais désarchiver depuis Jira
      return currentStatus === 'archived';
    }
    // description et dueDate: toujours écrasés
    return false;
  } else if (source === 'tfs') {
    // Pour TFS, tous les champs sont écrasés (aucun n'est préservé)
    return false;
  }
  // Pour 'manual', pas de synchronisation
  return false;
}

/**
 * Interface pour les données de synchronisation d'une tâche
 */
export interface SyncTaskData {
  title: string;
  description: string | null;
  status: string;
  priority: string;
  dueDate: Date | null;
}

/**
 * Interface pour les données existantes d'une tâche
 */
export interface ExistingTaskData {
  title: string;
  description: string | null;
  status: string;
  priority: string;
  dueDate: Date | null;
}

/**
 * Construit les données de mise à jour en appliquant la logique de préservation centralisée
 * @param source - Source de la tâche (jira, tfs, manual)
 * @param existingTask - Données existantes de la tâche
 * @param syncData - Données venant de la source externe
 * @returns Données finales à utiliser pour la mise à jour
 */
export function buildSyncUpdateData(
  source: TaskSource,
  existingTask: ExistingTaskData,
  syncData: SyncTaskData
): SyncTaskData {
  const currentStatus = existingTask.status as TaskStatus;

  return {
    title: shouldPreserveFieldDuringSync(
      source,
      'title',
      existingTask.title,
      syncData.title
    )
      ? existingTask.title
      : syncData.title,

    description: shouldPreserveFieldDuringSync(
      source,
      'description',
      existingTask.description,
      syncData.description
    )
      ? existingTask.description
      : syncData.description,

    status: shouldPreserveFieldDuringSync(
      source,
      'status',
      existingTask.status,
      syncData.status,
      currentStatus
    )
      ? existingTask.status
      : syncData.status,

    priority: shouldPreserveFieldDuringSync(
      source,
      'priority',
      existingTask.priority,
      syncData.priority
    )
      ? existingTask.priority
      : syncData.priority,

    dueDate: shouldPreserveFieldDuringSync(
      source,
      'dueDate',
      existingTask.dueDate,
      syncData.dueDate
    )
      ? existingTask.dueDate
      : syncData.dueDate,
  };
}
