import { Injectable, ForbiddenException, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import {
  TenantORM,
  TenantStatus,
  TenantPlan,
  TenantConfigData,
} from '../../../infrastructure/database/postgres/entities/tenant.orm';
import { AdminORM } from '../../../infrastructure/database/postgres/entities/admin.orm';

export interface CreateTenantDto {
  name: string;
  slug: string;
  plan?: 'FREE' | 'STANDARD' | 'ENTERPRISE';
  maxUsers?: number;
  maxConversationsPerMonth?: number;
  maxStorageMb?: number;
  billingEmail?: string;
  billingName?: string;
  billingPhone?: string;
  config?: Record<string, any>;
}

export interface UpdateTenantDto {
  name?: string;
  plan?: 'FREE' | 'STANDARD' | 'ENTERPRISE';
  maxUsers?: number;
  maxConversationsPerMonth?: number;
  maxStorageMb?: number;
  billingEmail?: string;
  billingName?: string;
  billingPhone?: string;
  config?: Record<string, any>;
}

export interface CreateTenantAdminDto {
  username: string;
  password: string;
  name: string;
  email?: string;
  phone?: string;
  role?: 'ADMIN' | 'OPERATOR' | 'VIEWER';
}

@Injectable()
export class TenantManagementService {
  constructor(
    @InjectRepository(TenantORM)
    private readonly tenantRepo: Repository<TenantORM>,
    @InjectRepository(AdminORM)
    private readonly adminRepo: Repository<AdminORM>,
  ) {}

  /**
   * 验证是否为超级管理员
   */
  async verifySuperAdmin(adminId: string): Promise<AdminORM> {
    const admin = await this.adminRepo.findOne({ where: { id: adminId } });
    if (!admin) {
      throw new NotFoundException('管理员不存在');
    }
    if (!admin.isSuperAdmin) {
      throw new ForbiddenException('需要超级管理员权限');
    }
    return admin;
  }

  /**
   * 获取所有租户列表
   */
  async listTenants(params?: {
    status?: string;
    plan?: string;
    page?: number;
    limit?: number;
  }): Promise<{ data: TenantORM[]; total: number }> {
    const { status, plan, page = 1, limit = 20 } = params || {};

    const query = this.tenantRepo.createQueryBuilder('tenant');

    if (status) {
      query.andWhere('tenant.status = :status', { status });
    }
    if (plan) {
      query.andWhere('tenant.plan = :plan', { plan });
    }

    const total = await query.getCount();
    const data = await query
      .orderBy('tenant.createdAt', 'DESC')
      .skip((page - 1) * limit)
      .take(limit)
      .getMany();

    return { data, total };
  }

  /**
   * 获取租户详情
   */
  async getTenant(tenantId: string): Promise<TenantORM> {
    const tenant = await this.tenantRepo.findOne({ where: { id: tenantId } });
    if (!tenant) {
      throw new NotFoundException('租户不存在');
    }
    return tenant;
  }

  /**
   * 创建租户
   */
  async createTenant(dto: CreateTenantDto): Promise<TenantORM> {
    // 检查 slug 是否已存在
    const existing = await this.tenantRepo.findOne({ where: { slug: dto.slug } });
    if (existing) {
      throw new ForbiddenException(`租户标识 ${dto.slug} 已存在`);
    }

    const tenant = this.tenantRepo.create({
      name: dto.name,
      slug: dto.slug,
      status: TenantStatus.ACTIVE,
      plan: (dto.plan as TenantPlan) || TenantPlan.STANDARD,
      maxUsers: dto.maxUsers || 100,
      maxConversationsPerMonth: dto.maxConversationsPerMonth || 10000,
      maxStorageMb: dto.maxStorageMb || 5120,
      billingEmail: dto.billingEmail || null,
      billingName: dto.billingName || null,
      billingPhone: dto.billingPhone || null,
      config: (dto.config || {}) as TenantConfigData,
    });

    return this.tenantRepo.save(tenant);
  }

  /**
   * 更新租户
   */
  async updateTenant(tenantId: string, dto: UpdateTenantDto): Promise<TenantORM> {
    const tenant = await this.getTenant(tenantId);

    if (dto.name !== undefined) tenant.name = dto.name;
    if (dto.plan !== undefined) tenant.plan = dto.plan as TenantPlan;
    if (dto.maxUsers !== undefined) tenant.maxUsers = dto.maxUsers;
    if (dto.maxConversationsPerMonth !== undefined) tenant.maxConversationsPerMonth = dto.maxConversationsPerMonth;
    if (dto.maxStorageMb !== undefined) tenant.maxStorageMb = dto.maxStorageMb;
    if (dto.billingEmail !== undefined) tenant.billingEmail = dto.billingEmail || null;
    if (dto.billingName !== undefined) tenant.billingName = dto.billingName || null;
    if (dto.billingPhone !== undefined) tenant.billingPhone = dto.billingPhone || null;
    if (dto.config !== undefined) tenant.config = { ...tenant.config, ...dto.config } as TenantConfigData;

    return this.tenantRepo.save(tenant);
  }

  /**
   * 暂停租户
   */
  async suspendTenant(tenantId: string, _reason?: string): Promise<TenantORM> {
    const tenant = await this.getTenant(tenantId);

    tenant.status = TenantStatus.SUSPENDED;
    tenant.suspendedAt = new Date();

    return this.tenantRepo.save(tenant);
  }

  /**
   * 激活租户
   */
  async activateTenant(tenantId: string): Promise<TenantORM> {
    const tenant = await this.getTenant(tenantId);

    tenant.status = TenantStatus.ACTIVE;
    tenant.suspendedAt = null;

    return this.tenantRepo.save(tenant);
  }

  /**
   * 归档租户
   */
  async archiveTenant(tenantId: string): Promise<TenantORM> {
    const tenant = await this.getTenant(tenantId);
    tenant.status = TenantStatus.ARCHIVED;
    return this.tenantRepo.save(tenant);
  }

  /**
   * 获取租户的管理员列表
   */
  async listTenantAdmins(tenantId: string): Promise<AdminORM[]> {
    return this.adminRepo.find({
      where: { tenantId },
      select: ['id', 'username', 'name', 'email', 'phone', 'role', 'isActive', 'lastLoginAt', 'createdAt'],
    });
  }

  /**
   * 为租户创建管理员
   */
  async createTenantAdmin(tenantId: string, dto: CreateTenantAdminDto): Promise<AdminORM> {
    // 验证租户存在
    await this.getTenant(tenantId);

    // 检查用户名是否已存在
    const existing = await this.adminRepo.findOne({ where: { username: dto.username } });
    if (existing) {
      throw new ForbiddenException(`用户名 ${dto.username} 已存在`);
    }

    // 加密密码
    const bcrypt = await import('bcrypt');
    const crypto = await import('crypto');
    const passwordHash = await bcrypt.hash(dto.password, 10);

    const admin = this.adminRepo.create({
      id: crypto.randomUUID(),
      tenantId,
      isSuperAdmin: false,
      username: dto.username,
      passwordHash,
      name: dto.name,
      email: dto.email,
      phone: dto.phone,
      role: dto.role || 'OPERATOR',
      permissions: [],
      isActive: true,
    });

    return this.adminRepo.save(admin);
  }

  /**
   * 获取租户统计摘要
   */
  async getTenantStats(tenantId: string): Promise<{
    userCount: number;
    conversationCount: number;
    storageUsed: number;
    adminCount: number;
  }> {
    const tenant = await this.getTenant(tenantId);
    const adminCount = await this.adminRepo.count({ where: { tenantId } });

    return {
      userCount: tenant.currentUserCount,
      conversationCount: tenant.currentConversationCount,
      storageUsed: tenant.currentStorageBytes,
      adminCount,
    };
  }

  /**
   * 获取所有租户的汇总统计
   */
  async getGlobalStats(): Promise<{
    totalTenants: number;
    activeTenants: number;
    suspendedTenants: number;
    totalUsers: number;
    totalConversations: number;
    totalStorage: number;
  }> {
    const tenants = await this.tenantRepo.find();

    return {
      totalTenants: tenants.length,
      activeTenants: tenants.filter(t => t.status === TenantStatus.ACTIVE).length,
      suspendedTenants: tenants.filter(t => t.status === TenantStatus.SUSPENDED).length,
      totalUsers: tenants.reduce((sum, t) => sum + t.currentUserCount, 0),
      totalConversations: tenants.reduce((sum, t) => sum + t.currentConversationCount, 0),
      totalStorage: tenants.reduce((sum, t) => sum + Number(t.currentStorageBytes), 0),
    };
  }
}
