import { KanbanStore, KanbanBoard, Task } from './types.js';
import { ConfigManager } from '../../config/config-manager.js';

export class KanbanDataStore {
  private store: KanbanStore = { boards: {} };
  private configManager: ConfigManager;
  private readonly MODULE_NAME = 'kanban';
  private readonly DATA_FILE = 'kanban.json';

  constructor(configManager?: ConfigManager) {
    this.configManager = configManager || new ConfigManager();
  }

  async init(): Promise<void> {
    const storageManager = this.configManager.getStorageManager();
    await storageManager.ensureStorageDirectories();
    
    const data = await storageManager.loadData(this.MODULE_NAME, this.DATA_FILE);
    if (data) {
      this.store = data;
    } else {
      // If file doesn't exist, create it with empty store
      await this.save();
    }
  }

  async save(): Promise<void> {
    const storageManager = this.configManager.getStorageManager();
    await storageManager.saveData(this.MODULE_NAME, this.DATA_FILE, this.store);
  }

  createBoard(name: string, columns: string[] = ['Backlog', 'To Do', 'In Progress', 'Review', 'Done']): KanbanBoard {
    const board: KanbanBoard = {
      id: this.generateId(),
      name,
      columns,
      tasks: [],
      createdAt: new Date(),
      updatedAt: new Date(),
    };
    
    this.store.boards[board.id] = board;
    return board;
  }

  getBoard(nameOrId: string): KanbanBoard | undefined {
    // Try to find by ID first
    if (this.store.boards[nameOrId]) {
      return this.store.boards[nameOrId];
    }
    
    // Try to find by name
    return Object.values(this.store.boards).find(board => board.name === nameOrId);
  }

  getAllBoards(): KanbanBoard[] {
    return Object.values(this.store.boards);
  }

  addTask(boardNameOrId: string, task: Omit<Task, 'id' | 'createdAt' | 'updatedAt'>): Task | null {
    const board = this.getBoard(boardNameOrId);
    if (!board) {
      return null;
    }

    const newTask: Task = {
      ...task,
      id: this.generateId(),
      createdAt: new Date(),
      updatedAt: new Date(),
      // Initialize new enhanced properties with defaults if not provided
      acceptanceCriteria: task.acceptanceCriteria || [],
      dependencies: task.dependencies || [],
      timeTracking: task.timeTracking || undefined,
      attachments: task.attachments || [],
      comments: task.comments || [],
      customFields: task.customFields || [],
      subtasks: task.subtasks || [],
      watchers: task.watchers || [],
      // Ensure tags is used instead of labels for consistency
      tags: task.tags || (task as any).labels || [],
    };

    board.tasks.push(newTask);
    board.updatedAt = new Date();
    return newTask;
  }

  moveTask(boardNameOrId: string, taskId: string, newColumn: string): boolean {
    const board = this.getBoard(boardNameOrId);
    if (!board) {
      return false;
    }

    const task = board.tasks.find(t => t.id === taskId);
    if (!task || !board.columns.includes(newColumn)) {
      return false;
    }

    task.column = newColumn;
    task.updatedAt = new Date();
    board.updatedAt = new Date();
    return true;
  }

  updateTask(boardNameOrId: string, taskId: string, updates: Partial<Omit<Task, 'id' | 'createdAt' | 'updatedAt'>>): boolean {
    const board = this.getBoard(boardNameOrId);
    if (!board) {
      return false;
    }

    const task = board.tasks.find(t => t.id === taskId);
    if (!task) {
      return false;
    }

    Object.assign(task, updates);
    task.updatedAt = new Date();
    board.updatedAt = new Date();
    return true;
  }

  deleteTask(boardNameOrId: string, taskId: string): boolean {
    const board = this.getBoard(boardNameOrId);
    if (!board) {
      return false;
    }

    const taskIndex = board.tasks.findIndex(t => t.id === taskId);
    if (taskIndex === -1) {
      return false;
    }

    board.tasks.splice(taskIndex, 1);
    board.updatedAt = new Date();
    return true;
  }

  private generateId(): string {
    return Date.now().toString(36) + Math.random().toString(36).substr(2);
  }
}