import { Injectable } from '@nestjs/common';
import { PrismaService } from '../prisma/prisma.service';
import {
  ClassificationRuleRepository,
  RuleWithTag,
} from '../../../domain/repositories/classification-rule.repository';
import {
  ClassificationRuleEntity,
  RuleConditions,
} from '../../../domain/entities/classification-rule.entity';

@Injectable()
export class ClassificationRuleRepositoryImpl
  implements ClassificationRuleRepository
{
  constructor(private readonly prisma: PrismaService) {}

  async save(rule: ClassificationRuleEntity): Promise<ClassificationRuleEntity> {
    const data = {
      id: rule.id,
      name: rule.name,
      description: rule.description,
      conditions: rule.conditions as object,
      isEnabled: rule.isEnabled,
      updatedAt: new Date(),
    };

    const result = await this.prisma.userClassificationRule.upsert({
      where: { id: rule.id },
      create: {
        ...data,
        createdAt: rule.createdAt,
      },
      update: data,
    });

    return this.mapToEntity(result);
  }

  async findById(id: string): Promise<ClassificationRuleEntity | null> {
    const result = await this.prisma.userClassificationRule.findUnique({
      where: { id },
    });

    return result ? this.mapToEntity(result) : null;
  }

  async findAll(params?: {
    isEnabled?: boolean;
    limit?: number;
    offset?: number;
  }): Promise<ClassificationRuleEntity[]> {
    const results = await this.prisma.userClassificationRule.findMany({
      where: params?.isEnabled !== undefined
        ? { isEnabled: params.isEnabled }
        : undefined,
      take: params?.limit,
      skip: params?.offset,
      orderBy: { createdAt: 'desc' },
    });

    return results.map((r) => this.mapToEntity(r));
  }

  async findEnabled(): Promise<ClassificationRuleEntity[]> {
    return this.findAll({ isEnabled: true });
  }

  async findLinkedRules(): Promise<RuleWithTag[]> {
    // 查找所有关联了标签的规则
    const tags = await this.prisma.userTag.findMany({
      where: {
        ruleId: { not: null },
      },
      include: {
        rule: true,
      },
    });

    return tags
      .filter((tag) => tag.rule !== null)
      .map((tag) => ({
        rule: this.mapToEntity(tag.rule!),
        tagId: tag.id,
        tagCode: tag.code,
      }));
  }

  async count(params?: { isEnabled?: boolean }): Promise<number> {
    return this.prisma.userClassificationRule.count({
      where: params?.isEnabled !== undefined
        ? { isEnabled: params.isEnabled }
        : undefined,
    });
  }

  async delete(id: string): Promise<void> {
    // 先解除与标签的关联
    await this.prisma.userTag.updateMany({
      where: { ruleId: id },
      data: { ruleId: null, type: 'MANUAL' },
    });

    await this.prisma.userClassificationRule.delete({
      where: { id },
    });
  }

  private mapToEntity(data: {
    id: string;
    name: string;
    description: string | null;
    conditions: unknown;
    isEnabled: boolean;
    createdAt: Date;
    updatedAt: Date;
  }): ClassificationRuleEntity {
    return new ClassificationRuleEntity(
      data.id,
      data.name,
      data.description,
      data.conditions as RuleConditions,
      data.isEnabled,
      data.createdAt,
      data.updatedAt,
    );
  }
}
