import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '@/infrastructure/persistence/prisma/prisma.service';
import { ApplicationError } from '@/shared/exceptions/domain.exception';
import {
  PendingActionStatus,
  CreatePendingActionDto,
  UpdatePendingActionDto,
  QueryPendingActionsDto,
  BatchCreatePendingActionDto,
} from '@/api/dto/request/pending-action.dto';
import {
  PendingActionResponseDto,
  PendingActionListResponseDto,
  BatchCreateResultDto,
} from '@/api/dto/response/pending-action.dto';

/**
 * 用户待办操作服务
 *
 * 提供用户待办操作的增删改查功能，用于后台配置指定用户登录后需要执行的特定操作。
 * 完全独立，不影响现有任何功能。
 */
@Injectable()
export class PendingActionService {
  private readonly logger = new Logger(PendingActionService.name);

  constructor(private readonly prisma: PrismaService) {}

  // ==================== 用户端接口 ====================

  /**
   * 获取当前用户的待办操作列表
   * 返回 PENDING 状态且未过期的操作，按优先级降序排列
   */
  async getMyPendingActions(userId: string): Promise<PendingActionResponseDto[]> {
    this.logger.log(`[PendingAction] Getting pending actions for user: ${userId}`);

    const now = new Date();
    const actions = await this.prisma.userPendingAction.findMany({
      where: {
        userId: BigInt(userId),
        status: PendingActionStatus.PENDING,
        OR: [
          { expiresAt: null },
          { expiresAt: { gt: now } },
        ],
      },
      orderBy: [
        { priority: 'desc' },
        { createdAt: 'asc' },
      ],
    });

    return actions.map((action) => this.toResponseDto(action));
  }

  /**
   * 用户标记操作完成
   */
  async completeAction(
    userId: string,
    actionId: string,
    resultData?: Record<string, any>,
  ): Promise<PendingActionResponseDto> {
    this.logger.log(`[PendingAction] Completing action: ${actionId} for user: ${userId}`);

    const action = await this.prisma.userPendingAction.findFirst({
      where: {
        id: BigInt(actionId),
        userId: BigInt(userId),
      },
    });

    if (!action) {
      throw new ApplicationError('操作不存在');
    }

    if (action.status !== PendingActionStatus.PENDING) {
      throw new ApplicationError('操作已完成或已取消');
    }

    const updated = await this.prisma.userPendingAction.update({
      where: { id: BigInt(actionId) },
      data: {
        status: PendingActionStatus.COMPLETED,
        completedAt: new Date(),
        // 如果有结果数据，合并到 actionParams 中
        ...(resultData && {
          actionParams: {
            ...(action.actionParams as object || {}),
            _result: resultData,
          },
        }),
      },
    });

    this.logger.log(`[PendingAction] Action completed: ${actionId}`);

    return this.toResponseDto(updated);
  }

  // ==================== 后台管理接口 ====================

  /**
   * 创建用户待办操作 (后台管理)
   * 支持通过 userId (纯数字) 或 accountSequence (如 D25122700022) 查找用户
   */
  async createAction(
    dto: CreatePendingActionDto,
    createdBy?: string,
  ): Promise<PendingActionResponseDto> {
    this.logger.log(`[PendingAction] Creating action for user: ${dto.userId}, code: ${dto.actionCode}`);

    // 查找用户：支持 userId (纯数字) 或 accountSequence (如 D25122700022)
    const user = await this.findUserByIdOrSequence(dto.userId);

    if (!user) {
      throw new ApplicationError('用户不存在');
    }

    const action = await this.prisma.userPendingAction.create({
      data: {
        userId: user.userId,
        actionCode: dto.actionCode,
        actionParams: dto.actionParams ?? undefined,
        priority: dto.priority ?? 0,
        expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,
        createdBy,
      },
    });

    this.logger.log(`[PendingAction] Action created: ${action.id}`);

    return this.toResponseDto(action);
  }

  /**
   * 批量创建用户待办操作 (后台管理)
   * 支持通过 userId (纯数字) 或 accountSequence (如 D25122700022) 查找用户
   */
  async batchCreateActions(
    dto: BatchCreatePendingActionDto,
    createdBy?: string,
  ): Promise<BatchCreateResultDto> {
    this.logger.log(`[PendingAction] Batch creating actions for ${dto.userIds.length} users, code: ${dto.actionCode}`);

    let successCount = 0;
    const failedUserIds: string[] = [];

    for (const userIdOrSequence of dto.userIds) {
      try {
        // 查找用户：支持 userId 或 accountSequence
        const user = await this.findUserByIdOrSequence(userIdOrSequence);

        if (!user) {
          failedUserIds.push(userIdOrSequence);
          continue;
        }

        await this.prisma.userPendingAction.create({
          data: {
            userId: user.userId,
            actionCode: dto.actionCode,
            actionParams: dto.actionParams ?? undefined,
            priority: dto.priority ?? 0,
            expiresAt: dto.expiresAt ? new Date(dto.expiresAt) : null,
            createdBy,
          },
        });

        successCount++;
      } catch (error) {
        this.logger.warn(`[PendingAction] Failed to create action for user: ${userIdOrSequence}, error: ${error.message}`);
        failedUserIds.push(userIdOrSequence);
      }
    }

    this.logger.log(`[PendingAction] Batch create result: success=${successCount}, failed=${failedUserIds.length}`);

    return {
      successCount,
      failedCount: failedUserIds.length,
      failedUserIds: failedUserIds.length > 0 ? failedUserIds : undefined,
    };
  }

  /**
   * 查询用户待办操作列表 (后台管理)
   * 支持通过 userId (纯数字) 或 accountSequence (如 D25122700022) 筛选用户
   */
  async queryActions(dto: QueryPendingActionsDto): Promise<PendingActionListResponseDto> {
    const page = dto.page ?? 1;
    const limit = dto.limit ?? 20;
    const skip = (page - 1) * limit;

    const where: any = {};

    if (dto.userId) {
      // 支持 userId 或 accountSequence 筛选
      const user = await this.findUserByIdOrSequence(dto.userId);
      if (user) {
        where.userId = user.userId;
      } else {
        // 用户不存在，返回空结果
        return { items: [], total: 0, page, limit };
      }
    }
    if (dto.actionCode) {
      where.actionCode = dto.actionCode;
    }
    if (dto.status) {
      where.status = dto.status;
    }

    const [items, total] = await Promise.all([
      this.prisma.userPendingAction.findMany({
        where,
        orderBy: [
          { createdAt: 'desc' },
        ],
        skip,
        take: limit,
      }),
      this.prisma.userPendingAction.count({ where }),
    ]);

    // 批量获取 accountSequence
    const accountSequenceMap = await this.getAccountSequenceMap(items.map((item) => item.userId));

    return {
      items: items.map((action) =>
        this.toResponseDto(action, accountSequenceMap.get(action.userId.toString())),
      ),
      total,
      page,
      limit,
    };
  }

  /**
   * 获取单个操作详情 (后台管理)
   */
  async getAction(actionId: string): Promise<PendingActionResponseDto> {
    const action = await this.prisma.userPendingAction.findUnique({
      where: { id: BigInt(actionId) },
    });

    if (!action) {
      throw new ApplicationError('操作不存在');
    }

    const accountSequence = await this.getAccountSequence(action.userId);
    return this.toResponseDto(action, accountSequence);
  }

  /**
   * 更新用户待办操作 (后台管理)
   */
  async updateAction(
    actionId: string,
    dto: UpdatePendingActionDto,
  ): Promise<PendingActionResponseDto> {
    this.logger.log(`[PendingAction] Updating action: ${actionId}`);

    const action = await this.prisma.userPendingAction.findUnique({
      where: { id: BigInt(actionId) },
    });

    if (!action) {
      throw new ApplicationError('操作不存在');
    }

    const updateData: any = {};

    if (dto.actionParams !== undefined) {
      updateData.actionParams = dto.actionParams;
    }
    if (dto.status !== undefined) {
      updateData.status = dto.status;
      if (dto.status === PendingActionStatus.COMPLETED) {
        updateData.completedAt = new Date();
      }
    }
    if (dto.priority !== undefined) {
      updateData.priority = dto.priority;
    }
    if (dto.expiresAt !== undefined) {
      updateData.expiresAt = dto.expiresAt ? new Date(dto.expiresAt) : null;
    }

    const updated = await this.prisma.userPendingAction.update({
      where: { id: BigInt(actionId) },
      data: updateData,
    });

    this.logger.log(`[PendingAction] Action updated: ${actionId}`);

    return this.toResponseDto(updated);
  }

  /**
   * 删除用户待办操作 (后台管理)
   */
  async deleteAction(actionId: string): Promise<void> {
    this.logger.log(`[PendingAction] Deleting action: ${actionId}`);

    const action = await this.prisma.userPendingAction.findUnique({
      where: { id: BigInt(actionId) },
    });

    if (!action) {
      throw new ApplicationError('操作不存在');
    }

    await this.prisma.userPendingAction.delete({
      where: { id: BigInt(actionId) },
    });

    this.logger.log(`[PendingAction] Action deleted: ${actionId}`);
  }

  /**
   * 取消用户待办操作 (后台管理)
   * 软删除，将状态改为 CANCELLED
   */
  async cancelAction(actionId: string): Promise<PendingActionResponseDto> {
    this.logger.log(`[PendingAction] Cancelling action: ${actionId}`);

    const action = await this.prisma.userPendingAction.findUnique({
      where: { id: BigInt(actionId) },
    });

    if (!action) {
      throw new ApplicationError('操作不存在');
    }

    if (action.status !== PendingActionStatus.PENDING) {
      throw new ApplicationError('只能取消待处理的操作');
    }

    const updated = await this.prisma.userPendingAction.update({
      where: { id: BigInt(actionId) },
      data: {
        status: PendingActionStatus.CANCELLED,
      },
    });

    this.logger.log(`[PendingAction] Action cancelled: ${actionId}`);

    return this.toResponseDto(updated);
  }

  // ==================== Helper Methods ====================

  /**
   * 通过 userId (纯数字) 或 accountSequence (如 D25122700022) 查找用户
   */
  private async findUserByIdOrSequence(
    userIdOrSequence: string,
  ): Promise<{ userId: bigint } | null> {
    // 检查是否是纯数字 (userId)
    if (/^\d+$/.test(userIdOrSequence)) {
      this.logger.log(`[findUserByIdOrSequence] 按 userId 查找: ${userIdOrSequence}`);
      const user = await this.prisma.userAccount.findUnique({
        where: { userId: BigInt(userIdOrSequence) },
        select: { userId: true },
      });
      this.logger.log(`[findUserByIdOrSequence] 查找结果: ${user ? '找到' : '未找到'}`);
      return user;
    }

    // 否则尝试通过 accountSequence 查找
    this.logger.log(`[findUserByIdOrSequence] 按 accountSequence 查找: ${userIdOrSequence}`);
    const user = await this.prisma.userAccount.findUnique({
      where: { accountSequence: userIdOrSequence },
      select: { userId: true },
    });
    this.logger.log(`[findUserByIdOrSequence] 查找结果: ${user ? '找到' : '未找到'}`);
    return user;
  }

  private toResponseDto(action: any, accountSequence?: string): PendingActionResponseDto {
    return {
      id: action.id.toString(),
      userId: action.userId.toString(),
      accountSequence,
      actionCode: action.actionCode,
      actionParams: action.actionParams as Record<string, any> | null,
      status: action.status,
      priority: action.priority,
      expiresAt: action.expiresAt,
      createdAt: action.createdAt,
      completedAt: action.completedAt,
      createdBy: action.createdBy,
    };
  }

  /**
   * 批量获取用户的 accountSequence
   */
  private async getAccountSequenceMap(userIds: bigint[]): Promise<Map<string, string>> {
    if (userIds.length === 0) return new Map();

    const uniqueUserIds = [...new Set(userIds.map((id) => id.toString()))];
    const users = await this.prisma.userAccount.findMany({
      where: { userId: { in: uniqueUserIds.map((id) => BigInt(id)) } },
      select: { userId: true, accountSequence: true },
    });

    const map = new Map<string, string>();
    for (const user of users) {
      if (user.accountSequence) {
        map.set(user.userId.toString(), user.accountSequence);
      }
    }
    return map;
  }

  /**
   * 获取单个用户的 accountSequence
   */
  private async getAccountSequence(userId: bigint): Promise<string | undefined> {
    const user = await this.prisma.userAccount.findUnique({
      where: { userId },
      select: { accountSequence: true },
    });
    return user?.accountSequence ?? undefined;
  }
}
