import {
  IsArray,
  IsBoolean,
  IsDateString,
  IsEnum,
  IsInt,
  IsOptional,
  IsString,
  IsUUID,
  MaxLength,
  Min,
} from 'class-validator';
import { Transform, Type } from 'class-transformer';
import { RobotLifecycleStage, RobotUsageType, RobotDisposalType } from '@prisma/client';

/**
 * 创建机器人 DTO (v3)
 *
 * RobotUnit 只存"不变属性"——状态、客户、位置等可变信息走 LifecycleEvent + Snapshot。
 * 创建时同事务建 Snapshot(currentStage=SUPPLY_PO_CREATED) + LifecycleEvent(eventType=stage_changed, fromStage=null, toStage=SUPPLY_PO_CREATED)。
 */
export class CreateRobotUnitDto {
  @IsUUID()
  modelId: string;

  @IsUUID()
  skuId: string;

  @IsEnum(RobotUsageType)
  usageType: RobotUsageType;

  @IsOptional()
  @IsUUID()
  purchaseOrderId?: string;

  @IsOptional()
  @IsUUID()
  purchaseOrderLineId?: string;

  @IsOptional()
  @IsUUID()
  originalSupplierId?: string;

  @IsOptional()
  @IsString()
  ffsn?: string;

  @IsOptional()
  @IsString()
  placeholderSnOrig?: string;

  @IsOptional()
  @IsString()
  supplierSn?: string;

  @IsOptional()
  @IsDateString()
  manufactureDate?: string;

  @IsOptional()
  @IsString()
  sapMaterialNo?: string;

  @IsOptional()
  metadata?: Record<string, any>;
}

/**
 * 更新机器人 DTO — 只允许更新不变属性
 *
 * 状态切换走 POST /robot-units/:id/change-stage（lifecycle controller）
 * 位置/客户切换分别走 location_moved / 各自业务表的事件
 */
export class UpdateRobotUnitDto {
  @IsOptional()
  @IsString()
  supplierSn?: string;

  @IsOptional()
  @IsEnum(RobotUsageType)
  usageType?: RobotUsageType;

  @IsOptional()
  @IsDateString()
  manufactureDate?: string;

  @IsOptional()
  @IsString()
  sapMaterialNo?: string;

  @IsOptional()
  @IsEnum(RobotDisposalType)
  disposalType?: RobotDisposalType;

  @IsOptional()
  @IsString()
  disposalNotes?: string;

  @IsOptional()
  metadata?: Record<string, any>;

  @IsOptional()
  @IsInt()
  @Min(0)
  @Type(() => Number)
  version?: number;
}

export class QueryRobotUnitDto {
  @IsOptional()
  @IsString()
  search?: string;

  @IsOptional()
  @IsArray()
  @IsEnum(RobotLifecycleStage, { each: true })
  @Transform(({ value }) => (typeof value === 'string' ? [value] : value))
  currentStage?: RobotLifecycleStage[];

  @IsOptional()
  @IsUUID()
  modelId?: string;

  @IsOptional()
  @IsUUID()
  skuId?: string;

  @IsOptional()
  @IsUUID()
  purchaseOrderId?: string;

  @IsOptional()
  @IsUUID()
  currentLocationId?: string;

  @IsOptional()
  @IsUUID()
  currentCustomerId?: string;

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  isHeld?: boolean;

  @IsOptional()
  @IsBoolean()
  @Transform(({ value }) => value === 'true' || value === true)
  includeDeleted?: boolean;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  page?: number = 1;

  @IsOptional()
  @IsInt()
  @Min(1)
  @Type(() => Number)
  limit?: number = 20;

  @IsOptional()
  @IsString()
  sortBy?: string = 'createdAt';

  @IsOptional()
  @IsString()
  sortOrder?: 'asc' | 'desc' = 'desc';
}

/**
 * 状态切换 DTO（单个 / 批量）
 */
export class ChangeStageDto {
  @IsEnum(RobotLifecycleStage)
  toStage: RobotLifecycleStage;

  @IsOptional()
  @IsString()
  reason?: string;

  @IsOptional()
  metadata?: Record<string, any>;

  @IsOptional()
  @IsInt()
  @Min(0)
  @Type(() => Number)
  version?: number;
}

export class BulkChangeStageDto {
  @IsArray()
  @IsUUID('4', { each: true })
  robotUnitIds: string[];

  @IsEnum(RobotLifecycleStage)
  toStage: RobotLifecycleStage;

  @IsOptional()
  @IsString()
  reason?: string;
}

/**
 * Hold / Unhold DTO
 */
export class HoldStageDto {
  @IsString()
  holdReason: string;
}

/**
 * Location move DTO
 */
export class MoveLocationDto {
  @IsUUID()
  toLocationId: string;

  @IsOptional()
  @IsString()
  reason?: string;
}

/**
 * 占位 SN 激活 DTO（07 RECEIVED 扫供应商物理标签）
 * 占位 SN → 正式 FFSN，原值保留 placeholderSnOrig，Supplier SN 扫码录入。
 */
export class ActivateSnDto {
  /** 扫供应商物理标签得到的 SN（必填） */
  @IsString()
  @MaxLength(64)
  supplierSn: string;

  /** 可选：业务方手动指定正式 FFSN（如从 SAP/D365 同步），不传则后端生成 */
  @IsOptional()
  @IsString()
  @MaxLength(64)
  ffsn?: string;

  /** 可选：激活后顺便推进 stage（默认不推进） */
  @IsOptional()
  @IsEnum(RobotLifecycleStage)
  advanceTo?: RobotLifecycleStage;

  @IsOptional()
  @IsString()
  reason?: string;
}
