/**
 * 数据库查询优化工具
 * 提供统一的查询构建和优化方法
 */

const { Op } = require('sequelize');

/**
 * 查询构建器类
 */
class QueryBuilder {
  constructor() {
    this.whereConditions = {};
    this.orderConditions = [];
    this.includeConditions = [];
    this.attributes = null;
    this.limit = null;
    this.offset = null;
    this.groupBy = null;
    this.having = null;
  }

  /**
   * 添加搜索条件
   * @param {string} field - 字段名
   * @param {*} value - 搜索值
   * @param {string} operator - 操作符
   * @returns {QueryBuilder} 查询构建器实例
   */
  search(field, value, operator = 'like') {
    if (!value || value.toString().trim() === '') {
      return this;
    }

    switch (operator) {
      case 'like':
        this.whereConditions[field] = { [Op.like]: `%${value}%` };
        break;
      case 'eq':
        this.whereConditions[field] = value;
        break;
      case 'ne':
        this.whereConditions[field] = { [Op.ne]: value };
        break;
      case 'gt':
        this.whereConditions[field] = { [Op.gt]: value };
        break;
      case 'gte':
        this.whereConditions[field] = { [Op.gte]: value };
        break;
      case 'lt':
        this.whereConditions[field] = { [Op.lt]: value };
        break;
      case 'lte':
        this.whereConditions[field] = { [Op.lte]: value };
        break;
      case 'in':
        this.whereConditions[field] = { [Op.in]: Array.isArray(value) ? value : [value] };
        break;
      case 'notIn':
        this.whereConditions[field] = { [Op.notIn]: Array.isArray(value) ? value : [value] };
        break;
      case 'between':
        if (Array.isArray(value) && value.length === 2) {
          this.whereConditions[field] = { [Op.between]: value };
        }
        break;
      case 'isNull':
        this.whereConditions[field] = { [Op.is]: null };
        break;
      case 'notNull':
        this.whereConditions[field] = { [Op.not]: null };
        break;
    }

    return this;
  }

  /**
   * 添加多字段搜索条件
   * @param {Array} fields - 字段数组
   * @param {*} value - 搜索值
   * @param {string} operator - 操作符
   * @returns {QueryBuilder} 查询构建器实例
   */
  searchMultiple(fields, value, operator = 'like') {
    if (!value || value.toString().trim() === '') {
      return this;
    }

    const searchConditions = fields.map(field => {
      switch (operator) {
        case 'like':
          return { [field]: { [Op.like]: `%${value}%` } };
        case 'eq':
          return { [field]: value };
        default:
          return { [field]: { [Op.like]: `%${value}%` } };
      }
    });

    if (this.whereConditions[Op.or]) {
      this.whereConditions[Op.or] = [...this.whereConditions[Op.or], ...searchConditions];
    } else {
      this.whereConditions[Op.or] = searchConditions;
    }

    return this;
  }

  /**
   * 添加日期范围条件
   * @param {string} field - 日期字段名
   * @param {string} startDate - 开始日期
   * @param {string} endDate - 结束日期
   * @returns {QueryBuilder} 查询构建器实例
   */
  dateRange(field, startDate, endDate) {
    if (startDate || endDate) {
      const dateCondition = {};
      if (startDate) {
        dateCondition[Op.gte] = new Date(startDate);
      }
      if (endDate) {
        dateCondition[Op.lte] = new Date(endDate);
      }
      this.whereConditions[field] = dateCondition;
    }
    return this;
  }

  /**
   * 添加状态条件
   * @param {string} field - 状态字段名
   * @param {*} status - 状态值
   * @returns {QueryBuilder} 查询构建器实例
   */
  status(field, status) {
    if (status !== null && status !== undefined && status !== '') {
      this.whereConditions[field] = status;
    }
    return this;
  }

  /**
   * 添加排序条件
   * @param {string} field - 排序字段
   * @param {string} direction - 排序方向 ('ASC' 或 'DESC')
   * @returns {QueryBuilder} 查询构建器实例
   */
  orderBy(field, direction = 'DESC') {
    this.orderConditions.push([field, direction.toUpperCase()]);
    return this;
  }

  /**
   * 添加分页条件
   * @param {number} page - 页码
   * @param {number} limit - 每页数量
   * @returns {QueryBuilder} 查询构建器实例
   */
  paginate(page = 1, limit = 10) {
    this.limit = parseInt(limit);
    this.offset = (parseInt(page) - 1) * this.limit;
    return this;
  }

  /**
   * 添加关联查询条件
   * @param {Object} include - 关联查询配置
   * @returns {QueryBuilder} 查询构建器实例
   */
  include(include) {
    this.includeConditions.push(include);
    return this;
  }

  /**
   * 设置查询字段
   * @param {Array|Object} attributes - 查询字段
   * @returns {QueryBuilder} 查询构建器实例
   */
  select(attributes) {
    this.attributes = attributes;
    return this;
  }

  /**
   * 添加分组条件
   * @param {string|Array} groupBy - 分组字段
   * @returns {QueryBuilder} 查询构建器实例
   */
  group(groupBy) {
    this.groupBy = groupBy;
    return this;
  }

  /**
   * 添加HAVING条件
   * @param {Object} having - HAVING条件
   * @returns {QueryBuilder} 查询构建器实例
   */
  having(having) {
    this.having = having;
    return this;
  }

  /**
   * 构建查询选项
   * @returns {Object} Sequelize查询选项
   */
  build() {
    const options = {
      where: this.whereConditions,
      order: this.orderConditions.length > 0 ? this.orderConditions : undefined,
      include: this.includeConditions.length > 0 ? this.includeConditions : undefined,
      attributes: this.attributes,
      limit: this.limit,
      offset: this.offset,
      group: this.groupBy,
      having: this.having
    };

    // 移除undefined值
    Object.keys(options).forEach(key => {
      if (options[key] === undefined) {
        delete options[key];
      }
    });

    return options;
  }

  /**
   * 重置查询构建器
   * @returns {QueryBuilder} 查询构建器实例
   */
  reset() {
    this.whereConditions = {};
    this.orderConditions = [];
    this.includeConditions = [];
    this.attributes = null;
    this.limit = null;
    this.offset = null;
    this.groupBy = null;
    this.having = null;
    return this;
  }
}

/**
 * 创建查询构建器实例
 * @returns {QueryBuilder} 查询构建器实例
 */
const createQueryBuilder = () => {
  return new QueryBuilder();
};

/**
 * 构建分页查询
 * @param {Object} Model - Sequelize模型
 * @param {Object} queryOptions - 查询选项
 * @param {Object} pagination - 分页参数
 * @returns {Promise<Object>} 分页查询结果
 */
const paginateQuery = async (Model, queryOptions, pagination = {}) => {
  const { page = 1, limit = 10 } = pagination;
  const offset = (page - 1) * limit;

  const options = {
    ...queryOptions,
    limit: parseInt(limit),
    offset: parseInt(offset)
  };

  const { count, rows } = await Model.findAndCountAll(options);

  return {
    data: rows,
    pagination: {
      current: parseInt(page),
      pageSize: parseInt(limit),
      total: count,
      totalPages: Math.ceil(count / limit)
    }
  };
};

/**
 * 构建统计查询
 * @param {Object} Model - Sequelize模型
 * @param {Object} queryOptions - 查询选项
 * @param {Array} groupFields - 分组字段
 * @returns {Promise<Object>} 统计查询结果
 */
const statsQuery = async (Model, queryOptions, groupFields = []) {
  const options = {
    ...queryOptions,
    attributes: [
      ...groupFields,
      [Model.sequelize.fn('COUNT', Model.sequelize.col('*')), 'count']
    ],
    group: groupFields
  };

  const results = await Model.findAll(options);
  
  return results.map(result => ({
    ...result.dataValues,
    count: parseInt(result.dataValues.count)
  }));
};

/**
 * 构建搜索查询
 * @param {Object} searchParams - 搜索参数
 * @param {Object} searchConfig - 搜索配置
 * @returns {Object} 搜索查询条件
 */
const buildSearchQuery = (searchParams, searchConfig) => {
  const queryBuilder = createQueryBuilder();

  // 处理搜索关键词
  if (searchParams.search && searchConfig.searchFields) {
    queryBuilder.searchMultiple(searchConfig.searchFields, searchParams.search);
  }

  // 处理状态筛选
  if (searchParams.status && searchConfig.statusField) {
    queryBuilder.status(searchConfig.statusField, searchParams.status);
  }

  // 处理日期范围
  if (searchParams.dateRange && searchConfig.dateField) {
    const { start, end } = searchParams.dateRange;
    queryBuilder.dateRange(searchConfig.dateField, start, end);
  }

  // 处理排序
  if (searchParams.sortBy && searchConfig.sortFields) {
    const sortField = searchConfig.sortFields[searchParams.sortBy] || searchParams.sortBy;
    queryBuilder.orderBy(sortField, searchParams.sortOrder || 'DESC');
  }

  // 处理分页
  if (searchParams.page && searchParams.limit) {
    queryBuilder.paginate(searchParams.page, searchParams.limit);
  }

  return queryBuilder.build();
};

/**
 * 常用查询配置
 */
const QUERY_CONFIGS = {
  // 智能设备查询配置
  smartDevices: {
    searchFields: ['deviceId', 'deviceName', 'serialNumber'],
    statusField: 'status',
    dateField: 'created_at',
    sortFields: {
      'created_at': 'created_at',
      'updated_at': 'updated_at',
      'device_name': 'deviceName',
      'status': 'status'
    }
  },
  
  // 养殖场查询配置
  farms: {
    searchFields: ['name', 'type', 'address'],
    statusField: 'status',
    dateField: 'created_at',
    sortFields: {
      'created_at': 'created_at',
      'updated_at': 'updated_at',
      'name': 'name',
      'type': 'type'
    }
  },
  
  // 预警查询配置
  alerts: {
    searchFields: ['deviceId', 'alertType', 'description'],
    statusField: 'status',
    dateField: 'alertTime',
    sortFields: {
      'alert_time': 'alertTime',
      'created_at': 'created_at',
      'alert_type': 'alertType',
      'level': 'level'
    }
  }
};

/**
 * 获取查询配置
 * @param {string} type - 查询类型
 * @returns {Object} 查询配置
 */
const getQueryConfig = (type) => {
  return QUERY_CONFIGS[type] || {};
};

module.exports = {
  QueryBuilder,
  createQueryBuilder,
  paginateQuery,
  statsQuery,
  buildSearchQuery,
  getQueryConfig,
  QUERY_CONFIGS
};
