import { Meteor } from 'meteor/meteor';
import { check } from 'meteor/check';
import Boards from '/models/boards';
import Lists from '/models/lists';
import Swimlanes from '/models/swimlanes';
import Cards from '/models/cards';

/**
 * Fix duplicate lists and swimlanes created by WeKan 8.10
 * This method identifies and removes duplicate lists while preserving cards
 */
Meteor.methods({
  'fixDuplicateLists.fixAllBoards'() {
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }

    if (process.env.DEBUG === 'true') {
      console.log('Starting duplicate lists fix for all boards...');
    }
    
    const allBoards = Boards.find({}).fetch();
    let totalFixed = 0;
    let totalBoardsProcessed = 0;

    for (const board of allBoards) {
      try {
        const result = fixDuplicateListsForBoard(board._id);
        totalFixed += result.fixed;
        totalBoardsProcessed++;
        
        if (result.fixed > 0 && process.env.DEBUG === 'true') {
          console.log(`Fixed ${result.fixed} duplicate lists in board "${board.title}" (${board._id})`);
        }
      } catch (error) {
        console.error(`Error fixing board ${board._id}:`, error);
      }
    }

    if (process.env.DEBUG === 'true') {
      console.log(`Duplicate lists fix completed. Processed ${totalBoardsProcessed} boards, fixed ${totalFixed} duplicate lists.`);
    }
    
    return {
      message: `Fixed ${totalFixed} duplicate lists across ${totalBoardsProcessed} boards`,
      totalFixed,
      totalBoardsProcessed
    };
  },

  'fixDuplicateLists.fixBoard'(boardId) {
    check(boardId, String);
    
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }

    return fixDuplicateListsForBoard(boardId);
  }
});

// Helper functions defined outside of Meteor.methods
function fixDuplicateListsForBoard(boardId) {
    if (process.env.DEBUG === 'true') {
      console.log(`Fixing duplicate lists for board ${boardId}...`);
    }
    
    // First, fix duplicate swimlanes
    const swimlaneResult = fixDuplicateSwimlanes(boardId);
    
    // Then, fix duplicate lists
    const listResult = fixDuplicateLists(boardId);
    
    return {
      boardId,
      fixedSwimlanes: swimlaneResult.fixed,
      fixedLists: listResult.fixed,
      fixed: swimlaneResult.fixed + listResult.fixed
    };
}

// Helper functions defined outside of Meteor.methods
function fixDuplicateSwimlanes(boardId) {
    const swimlanes = Swimlanes.find({ boardId }).fetch();
    const swimlaneGroups = {};
    let fixed = 0;

    // Group swimlanes by title
    swimlanes.forEach(swimlane => {
      const key = swimlane.title || 'Default';
      if (!swimlaneGroups[key]) {
        swimlaneGroups[key] = [];
      }
      swimlaneGroups[key].push(swimlane);
    });

    // For each group with duplicates, keep the oldest and remove the rest
    Object.keys(swimlaneGroups).forEach(title => {
      const group = swimlaneGroups[title];
      if (group.length > 1) {
        // Sort by creation date, keep the oldest
        group.sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
        const keepSwimlane = group[0];
        const removeSwimlanes = group.slice(1);

        if (process.env.DEBUG === 'true') {
          console.log(`Found ${group.length} duplicate swimlanes with title "${title}", keeping oldest (${keepSwimlane._id})`);
        }

        // Move all lists from duplicate swimlanes to the kept swimlane
        removeSwimlanes.forEach(swimlane => {
          const lists = Lists.find({ swimlaneId: swimlane._id }).fetch();
          lists.forEach(list => {
            // Check if a list with the same title already exists in the kept swimlane
            const existingList = Lists.findOne({
              boardId,
              swimlaneId: keepSwimlane._id,
              title: list.title
            });

            if (existingList) {
              // Move cards to existing list
              Cards.update(
                { listId: list._id },
                { $set: { listId: existingList._id } },
                { multi: true }
              );
              // Remove duplicate list
              Lists.remove(list._id);
              if (process.env.DEBUG === 'true') {
                console.log(`Moved cards from duplicate list "${list.title}" to existing list in kept swimlane`);
              }
            } else {
              // Move list to kept swimlane
              Lists.update(list._id, { $set: { swimlaneId: keepSwimlane._id } });
              if (process.env.DEBUG === 'true') {
                console.log(`Moved list "${list.title}" to kept swimlane`);
              }
            }
          });

          // Remove duplicate swimlane
          Swimlanes.remove(swimlane._id);
          fixed++;
        });
      }
    });

    return { fixed };
}

function fixDuplicateLists(boardId) {
    const lists = Lists.find({ boardId }).fetch();
    const listGroups = {};
    let fixed = 0;

    // Group lists by title and swimlaneId
    lists.forEach(list => {
      const key = `${list.swimlaneId || 'null'}-${list.title}`;
      if (!listGroups[key]) {
        listGroups[key] = [];
      }
      listGroups[key].push(list);
    });

    // For each group with duplicates, keep the oldest and remove the rest
    Object.keys(listGroups).forEach(key => {
      const group = listGroups[key];
      if (group.length > 1) {
        // Sort by creation date, keep the oldest
        group.sort((a, b) => new Date(a.createdAt || 0) - new Date(b.createdAt || 0));
        const keepList = group[0];
        const removeLists = group.slice(1);

        if (process.env.DEBUG === 'true') {
          console.log(`Found ${group.length} duplicate lists with title "${keepList.title}" in swimlane ${keepList.swimlaneId}, keeping oldest (${keepList._id})`);
        }

        // Move all cards from duplicate lists to the kept list
        removeLists.forEach(list => {
          Cards.update(
            { listId: list._id },
            { $set: { listId: keepList._id } },
            { multi: true }
          );
          
          // Remove duplicate list
          Lists.remove(list._id);
          fixed++;
          if (process.env.DEBUG === 'true') {
            console.log(`Moved cards from duplicate list "${list.title}" to kept list`);
          }
        });
      }
    });

    return { fixed };
}

Meteor.methods({
  'fixDuplicateLists.getReport'() {
    if (!this.userId) {
      throw new Meteor.Error('not-authorized');
    }

    const allBoards = Boards.find({}).fetch();
    const report = [];

    for (const board of allBoards) {
      const swimlanes = Swimlanes.find({ boardId: board._id }).fetch();
      const lists = Lists.find({ boardId: board._id }).fetch();
      
      // Check for duplicate swimlanes
      const swimlaneGroups = {};
      swimlanes.forEach(swimlane => {
        const key = swimlane.title || 'Default';
        if (!swimlaneGroups[key]) {
          swimlaneGroups[key] = [];
        }
        swimlaneGroups[key].push(swimlane);
      });

      // Check for duplicate lists
      const listGroups = {};
      lists.forEach(list => {
        const key = `${list.swimlaneId || 'null'}-${list.title}`;
        if (!listGroups[key]) {
          listGroups[key] = [];
        }
        listGroups[key].push(list);
      });

      const duplicateSwimlanes = Object.values(swimlaneGroups).filter(group => group.length > 1);
      const duplicateLists = Object.values(listGroups).filter(group => group.length > 1);

      if (duplicateSwimlanes.length > 0 || duplicateLists.length > 0) {
        report.push({
          boardId: board._id,
          boardTitle: board.title,
          duplicateSwimlanes: duplicateSwimlanes.length,
          duplicateLists: duplicateLists.length,
          totalSwimlanes: swimlanes.length,
          totalLists: lists.length
        });
      }
    }

    return {
      totalBoards: allBoards.length,
      boardsWithDuplicates: report.length,
      report
    };
  }
});

