import {
  Controller,
  Get,
  Put,
  Body,
  Param,
  HttpCode,
  HttpStatus,
  Inject,
  Query,
} from '@nestjs/common';
import {
  SYSTEM_CONFIG_REPOSITORY,
  ISystemConfigRepository,
} from '../../domain/repositories/system-config.repository';

/**
 * 系统配置常量 - 热度展示设置
 */
export const CONFIG_KEYS = {
  // 是否允许未认种用户查看各省认种热度
  ALLOW_NON_ADOPTER_VIEW_HEAT: 'display.allowNonAdopterViewHeat',
  // 热度展示方式: 'count' | 'level'
  HEAT_DISPLAY_MODE: 'display.heatDisplayMode',
} as const;

/**
 * 获取系统配置响应 DTO
 */
interface SystemConfigResponseDto {
  key: string;
  value: string;
  description: string | null;
  updatedAt: Date;
}

/**
 * 前端展示设置响应 DTO
 */
interface DisplaySettingsResponseDto {
  allowNonAdopterViewHeat: boolean;
  heatDisplayMode: 'count' | 'level';
}

/**
 * 前端展示设置请求 DTO
 */
interface UpdateDisplaySettingsDto {
  allowNonAdopterViewHeat?: boolean;
  heatDisplayMode?: 'count' | 'level';
}

/**
 * 管理端系统配置控制器
 */
@Controller('admin/system-config')
export class AdminSystemConfigController {
  constructor(
    @Inject(SYSTEM_CONFIG_REPOSITORY)
    private readonly configRepo: ISystemConfigRepository,
  ) {}

  /**
   * 获取所有系统配置
   */
  @Get()
  async getAll(): Promise<SystemConfigResponseDto[]> {
    const configs = await this.configRepo.findAll();
    return configs.map((c) => ({
      key: c.key,
      value: c.value,
      description: c.description,
      updatedAt: c.updatedAt,
    }));
  }

  /**
   * 获取单个配置
   */
  @Get(':key')
  async getByKey(@Param('key') key: string): Promise<SystemConfigResponseDto | null> {
    const config = await this.configRepo.findByKey(key);
    if (!config) {
      return null;
    }
    return {
      key: config.key,
      value: config.value,
      description: config.description,
      updatedAt: config.updatedAt,
    };
  }

  /**
   * 获取前端展示设置
   */
  @Get('display/settings')
  async getDisplaySettings(): Promise<DisplaySettingsResponseDto> {
    const configs = await this.configRepo.findByKeys([
      CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT,
      CONFIG_KEYS.HEAT_DISPLAY_MODE,
    ]);

    const configMap = new Map(configs.map((c) => [c.key, c.value]));

    return {
      allowNonAdopterViewHeat:
        configMap.get(CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT) === 'true',
      heatDisplayMode:
        (configMap.get(CONFIG_KEYS.HEAT_DISPLAY_MODE) as 'count' | 'level') || 'count',
    };
  }

  /**
   * 更新前端展示设置
   */
  @Put('display/settings')
  @HttpCode(HttpStatus.OK)
  async updateDisplaySettings(
    @Body() dto: UpdateDisplaySettingsDto,
  ): Promise<DisplaySettingsResponseDto> {
    const updates: Array<{ key: string; value: string; description?: string }> = [];

    if (dto.allowNonAdopterViewHeat !== undefined) {
      updates.push({
        key: CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT,
        value: String(dto.allowNonAdopterViewHeat),
        description: '是否允许未认种用户查看各省认种热度',
      });
    }

    if (dto.heatDisplayMode !== undefined) {
      updates.push({
        key: CONFIG_KEYS.HEAT_DISPLAY_MODE,
        value: dto.heatDisplayMode,
        description: '热度展示方式: count=显示具体数量, level=仅显示热度等级',
      });
    }

    if (updates.length > 0) {
      await this.configRepo.batchUpsert(updates, 'admin');
    }

    // 返回更新后的配置
    return this.getDisplaySettings();
  }

  /**
   * 更新单个配置
   */
  @Put(':key')
  @HttpCode(HttpStatus.OK)
  async updateByKey(
    @Param('key') key: string,
    @Body() body: { value: string; description?: string },
  ): Promise<SystemConfigResponseDto> {
    const config = await this.configRepo.upsert(
      key,
      body.value,
      body.description,
      'admin',
    );
    return {
      key: config.key,
      value: config.value,
      description: config.description,
      updatedAt: config.updatedAt,
    };
  }
}

/**
 * 移动端/公开系统配置控制器
 * 用于 mobile-app 获取展示相关的配置
 */
@Controller('system-config')
export class PublicSystemConfigController {
  constructor(
    @Inject(SYSTEM_CONFIG_REPOSITORY)
    private readonly configRepo: ISystemConfigRepository,
  ) {}

  /**
   * 获取前端展示设置（公开接口）
   */
  @Get('display/settings')
  async getDisplaySettings(): Promise<DisplaySettingsResponseDto> {
    const configs = await this.configRepo.findByKeys([
      CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT,
      CONFIG_KEYS.HEAT_DISPLAY_MODE,
    ]);

    const configMap = new Map(configs.map((c) => [c.key, c.value]));

    return {
      allowNonAdopterViewHeat:
        configMap.get(CONFIG_KEYS.ALLOW_NON_ADOPTER_VIEW_HEAT) === 'true',
      heatDisplayMode:
        (configMap.get(CONFIG_KEYS.HEAT_DISPLAY_MODE) as 'count' | 'level') || 'count',
    };
  }
}
