import { ApiProperty } from '@nestjs/swagger';
import { AudioOptionItem } from '../../../features/files/types/types';
import { Type } from 'class-transformer';
import {
  IsArray,
  IsIn,
  IsInt,
  IsOptional,
  Min,
  ValidateNested,
} from 'class-validator';
import { TASK_LIST_SORTABLE_ATTRIBUTES } from '../../../constants';
import { IsStatus } from '../../../common/validators/status.validator';
import { Typist } from '../../../features/accounts/types/types';
import { IsAssignees } from '../../../common/validators/assignees.validator';

export class TasksRequest {
  @ApiProperty({
    required: false,
    default: 200,
    description: 'タスクの取得件数（指定しない場合はデフォルト値）',
  })
  @IsInt()
  @Min(0)
  @Type(() => Number)
  @IsOptional()
  @Type(() => Number)
  limit: number;

  @ApiProperty({
    required: false,
    default: 0,
    description:
      'オフセット（何件目から取得するか　設定しない場合はデフォルト値）',
  })
  @IsInt()
  @Min(0)
  @Type(() => Number)
  @IsOptional()
  @Type(() => Number)
  offset: number;

  @ApiProperty({
    required: false,
    description:
      '取得対象とするタスクのステータス。カンマ(,)区切りで複数指定可能。設定されない場合はすべてのステータスを取得対象とする。許容するステータスの値は次の通り: Uploaded / Pending / InProgress / Finished / Backup',
    example: 'Uploaded,Pending,InProgress',
  })
  @IsOptional()
  @IsStatus()
  status?: string;

  @ApiProperty({
    required: false,
    description: 'ASC/DESC',
  })
  @IsIn(['ASC', 'DESC'], { message: 'invalid direction' })
  @IsOptional()
  direction?: string;

  @ApiProperty({
    required: false,
    description: `${TASK_LIST_SORTABLE_ATTRIBUTES.join('/')}`,
  })
  @IsIn(TASK_LIST_SORTABLE_ATTRIBUTES, {
    message: 'invalid attributes',
  })
  @IsOptional()
  paramName?: string;
}

export class Assignee {
  @ApiProperty({
    required: false,
    description: 'TypistID（TypistIDかTypistGroupIDのどちらかに値が入る）',
  })
  @IsInt()
  @Min(1)
  @IsOptional()
  typistUserId?: number | undefined;
  @ApiProperty({
    required: false,
    description: 'TypistGroupID（TypistGroupIDかTypistIDのどちらかに値が入る）',
  })
  @IsInt()
  @Min(1)
  @IsOptional()
  typistGroupId?: number | undefined;
  @ApiProperty({ description: 'Typist名 / TypistGroup名' })
  typistName: string;
}

export class Task {
  @ApiProperty({ description: 'ODMS Cloud上の音声ファイルID' })
  audioFileId: number;
  @ApiProperty({ description: 'AuthorID' })
  authorId: string;
  @ApiProperty()
  workType: string;
  @ApiProperty({
    type: [AudioOptionItem],
    maxItems: 10,
    minItems: 10,
    description: '音声ファイルに紐づくOption Itemの一覧（10個固定）',
  })
  optionItemList: AudioOptionItem[];
  @ApiProperty({
    description:
      '音声ファイルのBlob Storage上での保存場所(ファイル名含む)のURL',
  })
  url: string;
  @ApiProperty({ description: '音声ファイル名' })
  fileName: string;
  @ApiProperty({
    description: '音声ファイルの録音時間（ミリ秒の整数値）',
  })
  audioDuration: string;
  @ApiProperty({
    description: '音声ファイルの録音開始日時（yyyy-mm-ddThh:mm:ss.sss）',
  })
  audioCreatedDate: string;
  @ApiProperty({
    description: '音声ファイルの録音終了日時（yyyy-mm-ddThh:mm:ss.sss）',
  })
  audioFinishedDate: string;
  @ApiProperty({
    description: '音声ファイルのアップロード日時（yyyy-mm-ddThh:mm:ss.sss）',
  })
  audioUploadedDate: string;
  @ApiProperty({ description: '音声ファイルのファイルサイズ（Byte）' })
  fileSize: number;
  @ApiProperty({ description: '音声ファイルの優先度 "00":Normal / "01":High' })
  priority: string;
  @ApiProperty({ description: '録音形式: DSS/DS2(SP)/DS2(QP)' })
  audioFormat: string;
  @ApiProperty({ description: 'コメント' })
  comment: string;
  @ApiProperty()
  isEncrypted: boolean;
  @ApiProperty({ description: 'JOBナンバー' })
  jobNumber: string;
  @ApiProperty({
    required: false,
    description: '割り当てられたユーザー',
  })
  typist?: Typist | undefined;
  @ApiProperty({
    type: [Assignee],
    description:
      '文字起こしに着手できる（チェックアウト可能な）、タスクにアサインされているグループ/個人の一覧',
  })
  assignees: Assignee[];
  @ApiProperty({
    description:
      '音声ファイルのファイルステータス Uploaded / Pending / InProgress / Finished / Backup',
  })
  status: string;
  @ApiProperty({
    required: false,
    description: '文字起こし開始日時（yyyy-mm-ddThh:mm:ss.sss）',
  })
  transcriptionStartedDate?: string | undefined;
  @ApiProperty({
    required: false,
    description: '文字起こし終了日時（yyyy-mm-ddThh:mm:ss.sss）',
  })
  transcriptionFinishedDate?: string | undefined;
}

export class TasksResponse {
  @ApiProperty({
    description: 'タスクの取得件数（指定しない場合はデフォルト値）',
  })
  limit: number;
  @ApiProperty({
    description:
      'オフセット（何件目から取得するか　設定しない場合はデフォルト値）',
  })
  offset: number;
  @ApiProperty({
    description: 'タスクの総件数',
  })
  total: number;

  @ApiProperty({
    type: [Task],
    description: '音声ファイル/タスク一覧',
  })
  tasks: Task[];
}
export class AudioNextRequest {
  @ApiProperty({ description: '文字起こし完了したタスクの音声ファイルID' })
  endedFileId: number;
}

export class AudioNextResponse {
  @ApiProperty({
    required: false,
    description: 'ODMS Cloud上の次の音声ファイルID（存在しなければundefind）',
  })
  nextFileId?: number | undefined;
}

export class ChangeStatusRequest {
  @ApiProperty({ description: 'ODMS Cloud上の音声ファイルID' })
  @Type(() => Number)
  @IsInt()
  @Min(1)
  audioFileId: number;
}

export class ChangeStatusResponse {}

export class PostCheckoutPermissionRequest {
  @ApiProperty({
    type: [Assignee],
    description:
      '文字起こしに着手可能（チェックアウト可能）にしたい、グループ個人の一覧',
  })
  @IsArray()
  @ValidateNested({ each: true })
  @Type(() => Assignee)
  @IsAssignees()
  assignees: Assignee[];
}

export class PostCheckoutPermissionResponse {}
