import { Injectable, Logger, NotFoundException } from '@nestjs/common';
import { PrismaService } from '@core/database/prisma/prisma.service';
import { RobotLifecycleStage } from '@prisma/client';

export interface FfsnRule {
  prefix: string;
  dateFormat: 'YYYYMM' | 'YYYY' | 'YYYYMMDD';
  seqLength: number;
  resetPeriod: 'MONTHLY' | 'YEARLY' | 'NEVER';
}

/** key -> value */
type ConfigMap = Record<string, any>;

@Injectable()
export class RobotSystemConfigService {
  private readonly logger = new Logger(RobotSystemConfigService.name);

  constructor(private readonly prisma: PrismaService) {}

  async list() {
    return this.prisma.robotSystemConfig.findMany({ orderBy: { key: 'asc' } });
  }

  async get<T = any>(key: string): Promise<T | null> {
    const row = await this.prisma.robotSystemConfig.findUnique({ where: { key } });
    return (row?.value as T) ?? null;
  }

  async set(key: string, value: any, description?: string) {
    return this.prisma.robotSystemConfig.upsert({
      where: { key },
      create: { key, value, description },
      update: { value, ...(description !== undefined ? { description } : {}) },
    });
  }

  async delete(key: string) {
    const existing = await this.prisma.robotSystemConfig.findUnique({ where: { key } });
    if (!existing) throw new NotFoundException(`config ${key} not found`);
    await this.prisma.robotSystemConfig.delete({ where: { key } });
    return { success: true };
  }

  // -------------- 业务语义 getter --------------

  async getFfsnRule(): Promise<FfsnRule> {
    const v = await this.get<Partial<FfsnRule>>('ffsn_rule');
    return {
      prefix: v?.prefix ?? 'FF',
      dateFormat: v?.dateFormat ?? 'YYYYMM',
      seqLength: v?.seqLength ?? 5,
      resetPeriod: v?.resetPeriod ?? 'MONTHLY',
    };
  }

  /**
   * 返回 status → locationCode 的默认映射（值为 null 表示由 status 推断）
   */
  async getStatusDefaultLocationMap(): Promise<Partial<Record<RobotLifecycleStage, string | null>>> {
    const v = await this.get<Partial<Record<RobotLifecycleStage, string | null>>>('status_default_location');
    return v ?? {};
  }

  async getRepairAutoServiceTypeCode(): Promise<string> {
    const v = await this.get<string>('repair_auto_service_type');
    return v ?? 'REPAIR';
  }
}
