import { ActionData } from '../models/ActionData';
import { DataPriority } from '../shared/types/shared/DataAbstractionLayer';

export class ActionDataService {
  async storeActionData(
    actionType: string,
    taskId: string,
    dataSource: string,
    data: any,
    priority: DataPriority
  ): Promise<ActionData> {
    const expiresAt = new Date(Date.now() + priority.expiration * 1000);

    try {
      const actionData = await ActionData.create({
        actionType,
        taskId,
        dataSource,
        data: JSON.stringify(data),
        priority: priority.level,
        weight: priority.weight,
        expiration: priority.expiration,
        timestamp: new Date(),
        expiresAt,
        metadata: JSON.stringify({
          dataSize: JSON.stringify(data).length,
          source: dataSource,
          action: actionType,
        }),
      });

      return actionData;
    } catch (error) {
      console.error('Failed to store action data:', error);
      throw error;
    }
  }

  async getActionData(
    actionType: string,
    taskId: string,
    dataSource?: string
  ): Promise<ActionData[]> {
    try {
      const query: any = {
        actionType,
        taskId,
        expiresAt: {
          [DataTypes.Op.gt]: new Date(),
        },
      };

      if (dataSource) {
        query.dataSource = dataSource;
      }

      const actionData = await ActionData.findAll({
        where: query,
        order: [['priority', 'ASC'], ['timestamp', 'DESC']],
      });

      return actionData;
    } catch (error) {
      console.error('Failed to get action data:', error);
      throw error;
    }
  }

  async getActionDataByPriority(
    actionType: string,
    taskId: string,
    priority: string
  ): Promise<ActionData[]> {
    try {
      const actionData = await ActionData.findAll({
        where: {
          actionType,
          taskId,
          priority,
          expiresAt: {
            [DataTypes.Op.gt]: new Date(),
          },
        },
        order: [['timestamp', 'DESC']],
      });

      return actionData;
    } catch (error) {
      console.error('Failed to get action data by priority:', error);
      throw error;
    }
  }

  async deleteActionData(taskId: string): Promise<number> {
    try {
      const deleted = await ActionData.destroy({
        where: {
          taskId,
        },
      });

      return deleted;
    } catch (error) {
      console.error('Failed to delete action data:', error);
      throw error;
    }
  }

  async cleanupExpiredData(): Promise<number> {
    try {
      const deleted = await ActionData.destroy({
        where: {
          expiresAt: {
            [DataTypes.Op.lte]: new Date(),
          },
        },
      });

      if (deleted > 0) {
        console.log(`Cleaned up ${deleted} expired action data records`);
      }

      return deleted;
    } catch (error) {
      console.error('Failed to cleanup expired action data:', error);
      throw error;
    }
  }

  async getActionDataStats(actionType?: string): Promise<{
    total: number;
    byPriority: Record<string, number>;
    byDataSource: Record<string, number>;
  }> {
    try {
      const query: any = {
        expiresAt: {
          [DataTypes.Op.gt]: new Date(),
        },
      };

      if (actionType) {
        query.actionType = actionType;
      }

      const allData = await ActionData.findAll({
        where: query,
      });

      const stats = {
        total: allData.length,
        byPriority: {
          critical: 0,
          high: 0,
          medium: 0,
          low: 0,
        },
        byDataSource: {} as Record<string, number>,
      };

      for (const data of allData) {
        stats.byPriority[data.priority]++;
        if (!stats.byDataSource[data.dataSource]) {
          stats.byDataSource[data.dataSource] = 0;
        }
        stats.byDataSource[data.dataSource]++;
      }

      return stats;
    } catch (error) {
      console.error('Failed to get action data stats:', error);
      throw error;
    }
  }
}

// 修复 DataTypes 引用
export const DataTypes = require('sequelize').DataTypes;

export const actionDataService = new ActionDataService();
