const mongoose = require('mongoose');

const MenuSchema = new mongoose.Schema({
  menuid: { type: String, required: true, unique: true }, // ID tùy chỉnh
  parent: { type: String, default: null }, // ID menu cha
  title: { type: String, required: true }, // Tên hiển thị
  url: { type: String, default: '' }, // Đường dẫn
  order: { type: Number, default: 0 }, // Thứ tự hiển thị
  type: { type: String, enum: ['static', 'page', 'level'], default: 'static' }, // Loại menu
  fetch: { type: Boolean, default: false }, // Có fetch programme không
  isActive: { type: Boolean, default: true } // Trạng thái hoạt động của menu
}, { timestamps: false });

// Index để tối ưu query
MenuSchema.index({ parent: 1, order: 1 });
MenuSchema.index({ type: 1 });

// Method để lấy menu tree
MenuSchema.statics.getMenuTree = async function () {
  try {
    const allMenus = await this.find().sort({ order: 1 }).lean();

    const menuMap = new Map();
    const rootMenus = [];

    // Đưa tất cả menus vào map và xử lý URL dựa trên isActive
    allMenus.forEach(menu => {
      const activeUrl = menu.isActive === false ? '/maintenance/' : menu.url;
      menuMap.set(menu.menuid, {
        ...menu,
        url: activeUrl, // Sử dụng URL đã được xử lý
        children: []
      });
    });

    // Xây dựng tree structure
    allMenus.forEach(menu => {
      const menuObj = menuMap.get(menu.menuid);

      if (!menu.parent) {
        rootMenus.push(menuObj);
      } else {
        const parent = menuMap.get(menu.parent);
        if (parent) {
          parent.children.push(menuObj);
        }
      }
    });

    return rootMenus;
  } catch (error) {
    console.error('Error building menu tree:', error);
    throw error;
  }
};

// Method để lấy menu tree với programmes
MenuSchema.statics.getMenuTreeWithProgrammes = async function () {
  try {
    const menuTree = await this.getMenuTree();

    // Thêm programmes cho các menu level
    for (const menu of menuTree) {
      await this.addProgrammesToMenu(menu);
    }

    return menuTree;
  } catch (error) {
    console.error('Error building menu tree with programmes:', error);
    throw error;
  }
};

// Method để thêm programmes vào menu
MenuSchema.statics.addProgrammesToMenu = async function (menuItem) {
  try {
    if (menuItem.type === 'level' && menuItem.fetch) {
      const programmes = await this.getProgrammesByMenuId(menuItem.menuid);
      menuItem.programmes = programmes;
    }

    if (menuItem.children && menuItem.children.length > 0) {
      for (const child of menuItem.children) {
        await this.addProgrammesToMenu(child);
      }
    }
  } catch (error) {
    console.error('Error adding programmes to menu:', error);
    throw error;
  }
};

// Method để lấy programmes theo menu ID
MenuSchema.statics.getProgrammesByMenuId = async function (menuId) {
  try {
    const Programme = require('./programme');
    const Level = require('./level');

    // Sử dụng trực tiếp menuId làm levelType vì menuid đã được đặt đúng khi tạo
    const levelType = menuId;

    const level = await Level.findOne({ type: levelType });
    if (!level) return [];

    const programmes = await Programme.find({ level: level._id })
      .select('name code level_type')
      .sort({ name: 1 })
      .lean();

    return programmes;
  } catch (error) {
    console.error('Error getting programmes by menu ID:', error);
    throw error;
  }
};

// Method để tạo menu mới
MenuSchema.statics.createMenu = async function (menuData) {
  try {
    const menu = new this(menuData);
    await menu.save();
    return menu;
  } catch (error) {
    console.error('Error creating menu:', error);
    throw error;
  }
};

// Method để cập nhật menu
MenuSchema.statics.updateMenu = async function (menuId, updateData) {
  try {
    const menu = await this.findOneAndUpdate({ menuid: menuId }, updateData, { new: true });
    return menu;
  } catch (error) {
    console.error('Error updating menu:', error);
    throw error;
  }
};

// Method để xóa menu
MenuSchema.statics.deleteMenu = async function (menuId) {
  try {
    // Xóa tất cả children trước
    await this.deleteMany({ parent: menuId });
    // Sau đó xóa menu chính
    const result = await this.findOneAndDelete({ menuid: menuId });
    return result;
  } catch (error) {
    console.error('Error deleting menu:', error);
    throw error;
  }
};

// Method để sắp xếp lại order
MenuSchema.statics.reorderMenus = async function (parentId, menuIds) {
  try {
    const updates = menuIds.map((menuId, index) => ({
      updateOne: {
        filter: { menuid: menuId },
        update: { order: index }
      }
    }));

    await this.bulkWrite(updates);
    console.log('Menus reordered successfully');
  } catch (error) {
    console.error('Error reordering menus:', error);
    throw error;
  }
};

// Method để lấy URL dựa trên trạng thái isActive
MenuSchema.methods.getActiveUrl = function () {
  if (this.isActive === false) {
    return '/maintenance/';
  }
  return this.url;
};

// Method để kiểm tra trạng thái hoạt động
MenuSchema.methods.isMenuActive = function () {
  return this.isActive !== false;
};

module.exports = mongoose.model('MenuHeader', MenuSchema);
