import { AppDataSource, SystemConfig, User, PlatformAccount, PublishTask } from '../models/index.js';
import type { SystemConfig as SystemConfigType } from '@media-manager/shared';
import { AVAILABLE_PLATFORM_TYPES } from '@media-manager/shared';
import { wsManager } from '../websocket/index.js';
import { RegionService, type ChinaRegionOption } from './RegionService.js';
import {
  checkPythonServiceHealth,
  getPythonServiceBaseUrl,
  invalidatePythonServiceBaseUrlCache,
} from './PythonServiceConfigService.js';

interface UpdateConfigParams {
  allowRegistration?: boolean;
  defaultUserRole?: string;
}

export interface PublishProxyAdminConfig {
  enabled: boolean;
  productKey: string;
  signature: string;
}

export interface UpdatePublishProxyAdminConfig {
  productKey?: string;
  signature?: string;
}

export interface PythonServiceAdminConfig {
  url: string;
  effectiveUrl: string;
}

export interface UpdatePythonServiceAdminConfig {
  url?: string;
}

interface SystemStatus {
  database: 'connected' | 'disconnected';
  redis: 'connected' | 'disconnected';
  onlineUsers: number;
  totalUsers: number;
  totalAccounts: number;
  totalTasks: number;
  uptime: number;
}

export class SystemService {
  private configRepository = AppDataSource.getRepository(SystemConfig);
  private userRepository = AppDataSource.getRepository(User);
  private accountRepository = AppDataSource.getRepository(PlatformAccount);
  private taskRepository = AppDataSource.getRepository(PublishTask);
  private regionService = new RegionService();

  async getPublicConfig(): Promise<SystemConfigType> {
    const configs = await this.configRepository.find();
    const configMap = new Map(configs.map(c => [c.configKey, c.configValue]));
    const productKey = (configMap.get('publish_proxy_shenlong_product_key') || '').trim();
    const signature = (configMap.get('publish_proxy_shenlong_signature') || '').trim();

    return {
      allowRegistration: configMap.get('allow_registration') === 'true',
      defaultUserRole: configMap.get('default_user_role') || 'operator',
      maxUploadSize: 4096 * 1024 * 1024, // 4GB
      supportedPlatforms: AVAILABLE_PLATFORM_TYPES,
      publishProxy: {
        enabled: Boolean(productKey && signature),
        provider: 'shenlong',
        cities: [],
      },
    };
  }

  async updateConfig(params: UpdateConfigParams): Promise<void> {
    if (params.allowRegistration !== undefined) {
      await this.setConfig('allow_registration', String(params.allowRegistration));
    }
    if (params.defaultUserRole) {
      await this.setConfig('default_user_role', params.defaultUserRole);
    }
  }

  async getPublishProxyAdminConfig(): Promise<PublishProxyAdminConfig> {
    const configs = await this.configRepository.find();
    const configMap = new Map(configs.map(c => [c.configKey, c.configValue]));

    const productKey = (configMap.get('publish_proxy_shenlong_product_key') || '').trim();
    const signature = (configMap.get('publish_proxy_shenlong_signature') || '').trim();

    return {
      enabled: Boolean(productKey && signature),
      productKey,
      signature,
    };
  }

  async updatePublishProxyAdminConfig(params: UpdatePublishProxyAdminConfig): Promise<void> {
    if (params.productKey !== undefined) {
      await this.setConfig('publish_proxy_shenlong_product_key', String(params.productKey || '').trim());
    }
    if (params.signature !== undefined) {
      await this.setConfig('publish_proxy_shenlong_signature', String(params.signature || '').trim());
    }
  }

  async getPythonServiceAdminConfig(): Promise<PythonServiceAdminConfig> {
    const configs = await this.configRepository.find();
    const configMap = new Map(configs.map(c => [c.configKey, c.configValue]));
    const url = (configMap.get('python_publish_service_url') || '').trim();
    const effectiveUrl = (await getPythonServiceBaseUrl()).trim();
    return { url, effectiveUrl };
  }

  async updatePythonServiceAdminConfig(params: UpdatePythonServiceAdminConfig): Promise<void> {
    if (params.url !== undefined) {
      await this.setConfig('python_publish_service_url', String(params.url || '').trim());
      invalidatePythonServiceBaseUrlCache();
    }
  }

  async checkPythonService(url?: string) {
    return checkPythonServiceHealth(url);
  }

  async getPublishProxyCitiesFromApi(): Promise<string[]> {
    const regions = await this.regionService.getChinaRegionsFromCsv();
    const citySet = new Set<string>();
    for (const province of regions) {
      for (const city of province.children || []) {
        const name = String(city.label || '').trim();
        if (name) citySet.add(name);
      }
    }
    return Array.from(citySet).sort((a, b) => a.localeCompare(b, 'zh-CN'));
  }

  async getPublishProxyRegionsFromCsv(): Promise<ChinaRegionOption[]> {
    return this.regionService.getChinaRegionsFromCsv();
  }

  async getSystemStatus(): Promise<SystemStatus> {
    const [totalUsers, totalAccounts, totalTasks] = await Promise.all([
      this.userRepository.count(),
      this.accountRepository.count(),
      this.taskRepository.count(),
    ]);

    return {
      database: AppDataSource.isInitialized ? 'connected' : 'disconnected',
      redis: 'connected', // TODO: 实际检查 Redis 连接状态
      onlineUsers: wsManager.getOnlineUserCount(),
      totalUsers,
      totalAccounts,
      totalTasks,
      uptime: process.uptime(),
    };
  }

  private async setConfig(key: string, value: string): Promise<void> {
    const existing = await this.configRepository.findOne({ where: { configKey: key } });
    if (existing) {
      await this.configRepository.update(existing.id, { configValue: value });
    } else {
      await this.configRepository.save({ configKey: key, configValue: value });
    }
  }
}
