import {
  Controller,
  Get,
  Post,
  Put,
  Body,
  Param,
  Query,
  Headers,
  HttpCode,
  HttpStatus,
  UnauthorizedException,
  ForbiddenException,
} from '@nestjs/common';
import { AdminService } from '../../application/services/admin.service';
import { AdminRole } from '../../domain/value-objects/admin-role.enum';
import {
  LoginDto,
  CreateAdminDto,
  UpdateAdminDto,
  ChangePasswordDto,
  ResetPasswordDto,
  LoginResult,
} from '../../application/dtos/admin.dto';

@Controller('admin')
export class AdminController {
  constructor(private adminService: AdminService) {}

  /**
   * 管理员登录
   */
  @Post('login')
  @HttpCode(HttpStatus.OK)
  async login(@Body() dto: LoginDto): Promise<{ success: boolean; data: LoginResult }> {
    try {
      const result = await this.adminService.login(dto.username, dto.password);
      return {
        success: true,
        data: result,
      };
    } catch (error) {
      throw new UnauthorizedException((error as Error).message);
    }
  }

  /**
   * 验证Token
   */
  @Get('verify')
  async verifyToken(@Headers('authorization') auth: string) {
    const token = auth?.replace('Bearer ', '');
    if (!token) {
      throw new UnauthorizedException('Missing token');
    }

    const result = await this.adminService.verifyToken(token);
    if (!result.valid) {
      throw new UnauthorizedException('Invalid token');
    }

    return {
      success: true,
      data: result.admin,
    };
  }

  /**
   * 获取当前管理员信息
   */
  @Get('me')
  async getCurrentAdmin(@Headers('authorization') auth: string) {
    const token = auth?.replace('Bearer ', '');
    const result = await this.adminService.verifyToken(token);

    if (!result.valid) {
      throw new UnauthorizedException('Invalid token');
    }

    return {
      success: true,
      data: result.admin,
    };
  }

  /**
   * 创建管理员（需要ADMIN权限）
   */
  @Post('admins')
  @HttpCode(HttpStatus.CREATED)
  async createAdmin(
    @Headers('authorization') auth: string,
    @Body() dto: CreateAdminDto,
  ) {
    await this.checkPermission(auth, 'admin:create');

    try {
      const admin = await this.adminService.createAdmin(dto);
      return {
        success: true,
        data: {
          id: admin.id,
          username: admin.username,
          name: admin.name,
          role: admin.role,
        },
      };
    } catch (error) {
      return {
        success: false,
        error: (error as Error).message,
      };
    }
  }

  /**
   * 获取管理员列表
   */
  @Get('admins')
  async listAdmins(
    @Headers('authorization') auth: string,
    @Query('role') role?: AdminRole,
    @Query('isActive') isActive?: string,
    @Query('page') page?: string,
    @Query('pageSize') pageSize?: string,
  ) {
    await this.checkPermission(auth, 'admin:read');

    const result = await this.adminService.listAdmins({
      role,
      isActive: isActive === undefined ? undefined : isActive === 'true',
      page: page ? parseInt(page) : 1,
      pageSize: pageSize ? parseInt(pageSize) : 20,
    });

    return {
      success: true,
      data: {
        items: result.items.map(a => ({
          id: a.id,
          username: a.username,
          name: a.name,
          email: a.email,
          phone: a.phone,
          role: a.role,
          isActive: a.isActive,
          lastLoginAt: a.lastLoginAt,
          createdAt: a.createdAt,
        })),
        total: result.total,
      },
    };
  }

  /**
   * 更新管理员
   */
  @Put('admins/:id')
  async updateAdmin(
    @Headers('authorization') auth: string,
    @Param('id') id: string,
    @Body() dto: UpdateAdminDto,
  ) {
    await this.checkPermission(auth, 'admin:update');

    try {
      const admin = await this.adminService.updateAdmin(id, dto);
      return {
        success: true,
        data: {
          id: admin.id,
          username: admin.username,
          name: admin.name,
          role: admin.role,
          isActive: admin.isActive,
        },
      };
    } catch (error) {
      return {
        success: false,
        error: (error as Error).message,
      };
    }
  }

  /**
   * 修改密码（当前用户）
   */
  @Post('change-password')
  async changePassword(
    @Headers('authorization') auth: string,
    @Body() dto: ChangePasswordDto,
  ) {
    const token = auth?.replace('Bearer ', '');
    const result = await this.adminService.verifyToken(token);

    if (!result.valid || !result.admin) {
      throw new UnauthorizedException('Invalid token');
    }

    try {
      await this.adminService.changePassword(
        result.admin.id,
        dto.oldPassword,
        dto.newPassword,
      );
      return {
        success: true,
        message: '密码修改成功',
      };
    } catch (error) {
      return {
        success: false,
        error: (error as Error).message,
      };
    }
  }

  /**
   * 重置密码（超管功能）
   */
  @Post('admins/:id/reset-password')
  async resetPassword(
    @Headers('authorization') auth: string,
    @Param('id') id: string,
    @Body() dto: ResetPasswordDto,
  ) {
    // 只有超管可以重置密码
    const token = auth?.replace('Bearer ', '');
    const result = await this.adminService.verifyToken(token);

    if (!result.valid || !result.admin) {
      throw new UnauthorizedException('Invalid token');
    }

    if (result.admin.role !== AdminRole.SUPER_ADMIN) {
      throw new ForbiddenException('Only super admin can reset passwords');
    }

    try {
      await this.adminService.resetPassword(id, dto.newPassword);
      return {
        success: true,
        message: '密码重置成功',
      };
    } catch (error) {
      return {
        success: false,
        error: (error as Error).message,
      };
    }
  }

  /**
   * 检查权限
   */
  private async checkPermission(auth: string, permission: string): Promise<void> {
    const token = auth?.replace('Bearer ', '');
    if (!token) {
      throw new UnauthorizedException('Missing token');
    }

    const result = await this.adminService.verifyToken(token);
    if (!result.valid || !result.admin) {
      throw new UnauthorizedException('Invalid token');
    }

    if (!this.adminService.hasPermission(result.admin.permissions, permission)) {
      throw new ForbiddenException(`Permission denied: ${permission}`);
    }
  }
}
