import { DataSource } from 'typeorm';
import { UserEntity } from '../entities/user.entity';
import { RoleService } from './role.service';
import { ConcreteCrudService } from '@d8d/shared-crud';
import * as bcrypt from 'bcrypt';

const SALT_ROUNDS = 10;

export class UserService extends ConcreteCrudService<UserEntity> {
  private roleService: RoleService;

  constructor(dataSource: DataSource) {
    super(UserEntity, {
      userTracking: {
        createdByField: 'createdBy',
        updatedByField: 'updatedBy'
      }
    });
    this.roleService = new RoleService(dataSource);
  }

  /**
   * 创建用户并加密密码
   */
  async createUser(userData: Partial<UserEntity>): Promise<UserEntity> {
    try {
      // 检查用户名是否已存在
      if (userData.username) {
        const existingUser = await this.getUserByUsername(userData.username);
        if (existingUser) {
          throw new Error('用户名已存在');
        }
      }

      if (userData.password) {
        userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS);
      }

      return await this.create(userData);
    } catch (error) {
      console.error('Error creating user:', error);
      throw new Error(`Failed to create user: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 根据用户名获取用户（自动添加租户过滤）
   */
  async getUserByUsername(username: string): Promise<UserEntity | null> {
    try {
      const where: any = { username };

      return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
    } catch (error) {
      console.error('Error getting user by username:', error);
      throw new Error('Failed to get user by username');
    }
  }

  /**
   * 根据手机号获取用户（自动添加租户过滤）
   */
  async getUserByPhone(phone: string): Promise<UserEntity | null> {
    try {
      const where: any = { phone };

      return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
    } catch (error) {
      console.error('Error getting user by phone:', error);
      throw new Error('Failed to get user by phone');
    }
  }

  /**
   * 根据账号（用户名或邮箱）获取用户（自动添加租户过滤）
   */
  async getUserByAccount(account: string): Promise<UserEntity | null> {
    try {
      const where: any = [
        { username: account },
        { email: account }
      ];

      return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
    } catch (error) {
      console.error('Error getting user by account:', error);
      throw new Error('Failed to get user by account');
    }
  }

  /**
   * 验证密码
   */
  async verifyPassword(user: UserEntity, password: string): Promise<boolean> {
    return password === user.password || bcrypt.compare(password, user.password);
  }

  /**
   * 为用户分配角色
   */
  async assignRoles(userId: number, roleIds: number[]): Promise<UserEntity | null> {
    try {
      const user = await this.getById(userId, ['roles']);
      if (!user) return null;

      // 获取角色实体
      const roles = [];
      for (const roleId of roleIds) {
        const role = await this.roleService.getById(roleId);
        if (role) {
          roles.push(role);
        }
      }

      // 分配角色
      user.roles = roles;
      return await this.repository.save(user);
    } catch (error) {
      console.error('Error assigning roles:', error);
      throw new Error('Failed to assign roles');
    }
  }

  /**
   * 根据ID获取用户（自动添加租户过滤）
   */
  async getUserById(id: number): Promise<UserEntity | null> {
    try {
      const where: any = { id };

      return await this.repository.findOne({ where, relations: ['roles', 'avatarFile'] });
    } catch (error) {
      console.error('Error getting user by id:', error);
      throw new Error('Failed to get user by id');
    }
  }

  /**
   * 更新用户信息（自动添加租户过滤）
   */
  async updateUser(id: number, userData: Partial<UserEntity>): Promise<UserEntity | null> {
    try {
      // 首先验证用户是否存在
      const existingUser = await this.getUserById(id);
      if (!existingUser) return null;

      // 如果更新密码，需要加密
      if (userData.password) {
        userData.password = await bcrypt.hash(userData.password, SALT_ROUNDS);
      }

      return await this.update(id, userData);
    } catch (error) {
      console.error('Error updating user:', error);
      throw new Error('Failed to update user');
    }
  }

  /**
   * 删除用户（自动添加租户过滤）
   */
  async deleteUser(id: number): Promise<boolean> {
    try {
      // 首先验证用户是否存在
      const existingUser = await this.getUserById(id);
      if (!existingUser) return false;

      return await this.delete(id);
    } catch (error) {
      console.error('Error deleting user:', error);
      throw new Error('Failed to delete user');
    }
  }

  /**
   * 获取所有用户（自动添加租户过滤）
   */
  async getUsers(): Promise<UserEntity[]> {
    try {
      const where: any = {};

      const [users] = await this.getList(1, 100, undefined, undefined, where, ['roles', 'avatarFile']);
      return users;
    } catch (error) {
      console.error('Error getting users:', error);
      throw new Error(`Failed to get users: ${error instanceof Error ? error.message : String(error)}`);
    }
  }

  /**
   * 获取用户信息，包含关联的企业详情
   */
  async getUserWithCompany(id: number): Promise<UserEntity | null> {
    try {
      const repository = this.repository;
      return await repository.findOne({
        where: { id },
        relations: ['company', 'roles', 'avatarFile']
      });
    } catch (error) {
      console.error('Error getting user with company:', error);
      throw new Error(`Failed to get user with company: ${error instanceof Error ? error.message : String(error)}`);
    }
  }
}