import { DataSource, Repository } from 'typeorm';
import { OrderRefundMt } from '../entities/order-refund.mt.entity';
import { OrderMt } from '../entities/order.mt.entity';
import { CreateOrderRefundDto, UpdateOrderRefundDto } from '../schemas/order-refund.schema';
import type { z } from 'zod';

export class UserRefundsMtService {
  private orderRefundRepository: Repository<OrderRefundMt>;
  private orderRepository: Repository<OrderMt>;

  constructor(dataSource: DataSource) {
    this.orderRefundRepository = dataSource.getRepository(OrderRefundMt);
    this.orderRepository = dataSource.getRepository(OrderMt);
  }

  /**
   * 获取当前用户的退款列表
   */
  async getUserRefundsList(
    page: number,
    pageSize: number,
    keyword?: string,
    userId?: number,
    tenantId?: number,
    filters?: any
  ): Promise<[OrderRefundMt[], number]> {
    if (!userId) {
      throw new Error('用户ID不能为空');
    }

    const queryBuilder = this.orderRefundRepository
      .createQueryBuilder('refund')
      .leftJoinAndSelect('refund.order', 'order')
      .where('order.userId = :userId', { userId });

    // 租户过滤
    if (tenantId) {
      queryBuilder.andWhere('refund.tenantId = :tenantId', { tenantId });
    }

    if (keyword) {
      queryBuilder.andWhere(
        '(refund.orderNo LIKE :keyword OR refund.refundOrderNo LIKE :keyword)',
        { keyword: `%${keyword}%` }
      );
    }

    // 处理状态过滤
    if (filters && filters.state !== undefined) {
      queryBuilder.andWhere('refund.state = :state', { state: filters.state });
    }

    const [data, total] = await queryBuilder
      .orderBy('refund.createdAt', 'DESC')
      .skip((page - 1) * pageSize)
      .take(pageSize)
      .getManyAndCount();

    return [data, total];
  }

  /**
   * 根据ID获取当前用户的退款详情
   */
  async getUserRefundById(id: number, userId?: number, tenantId?: number): Promise<OrderRefundMt | null> {
    if (!userId) {
      throw new Error('用户ID不能为空');
    }

    const queryBuilder = this.orderRefundRepository
      .createQueryBuilder('refund')
      .leftJoinAndSelect('refund.order', 'order')
      .where('refund.id = :id', { id });

    // 租户过滤
    if (tenantId) {
      queryBuilder.andWhere('refund.tenantId = :tenantId', { tenantId });
    }

    const refund = await queryBuilder.getOne();

    if (!refund) {
      return null;
    }

    // 检查权限
    if (refund.order.userId !== userId) {
      throw new Error('无权访问该退款记录');
    }

    return refund;
  }

  /**
   * 为当前用户创建退款
   */
  async createUserRefund(data: z.infer<typeof CreateOrderRefundDto>, userId?: number, tenantId?: number): Promise<OrderRefundMt> {
    if (!userId) {
      throw new Error('用户ID不能为空');
    }

    // 验证订单是否属于当前用户
    const order = await this.orderRepository.findOne({
      where: {
        orderNo: data.orderNo || undefined,
        userId,
        ...(tenantId && { tenantId })
      }
    });

    if (!order) {
      throw new Error('订单不存在或无权为该订单创建退款');
    }

    const refund = this.orderRefundRepository.create({
      ...data,
      tenantId,
      createdBy: userId,
      updatedBy: userId
    });

    return await this.orderRefundRepository.save(refund);
  }

  /**
   * 更新当前用户的退款
   */
  async updateUserRefund(
    id: number,
    data: z.infer<typeof UpdateOrderRefundDto>,
    userId?: number,
    tenantId?: number
  ): Promise<OrderRefundMt | null> {
    if (!userId) {
      throw new Error('用户ID不能为空');
    }

    // 验证退款是否属于当前用户
    const existingRefund = await this.getUserRefundById(id, userId, tenantId);
    if (!existingRefund) {
      return null;
    }

    const updatedRefund = this.orderRefundRepository.merge(existingRefund, {
      ...data,
      updatedBy: userId
    });

    return await this.orderRefundRepository.save(updatedRefund);
  }

  /**
   * 删除当前用户的退款
   */
  async deleteUserRefund(id: number, userId?: number, tenantId?: number): Promise<boolean> {
    if (!userId) {
      throw new Error('用户ID不能为空');
    }

    // 验证退款是否属于当前用户
    const existingRefund = await this.getUserRefundById(id, userId, tenantId);
    if (!existingRefund) {
      return false;
    }

    await this.orderRefundRepository.remove(existingRefund);
    return true;
  }
}