interface AuthedRequest {
  token?: string
  user_id?: number
}

interface BaseResponse<T> {
  ret: number
  msg: string
  data: T
}

// TODO: PagedData schema
interface PagedData<T> {
  total: number
  page: number
  perpage: number
  items: T[]
}

interface PagedDataRequest {
  page?: number
  perpage?: number
  to_user_id?: number
}

interface UserSchema {
  id: number
  username: string
  nickname: string
  avatar: string
  sex: 0 | 1 | 2 // 0: 未知, 1: 男, 2: 女
  email: string
  mobile: string
  auth_code: 0 | 1 | 2 // 0: Banned, 1: User, 2: Operator
  company?: string
}

type ServiceTag =
  | 'PPTToVideo'
  | 'TextToVideo'
  | 'SparkChat15'
  | 'SparkChat30'
  | 'SparkChat35'
  | 'TenTextToImg'
  | 'TenImgToImg'

interface ServiceType {
  name: string
  tag: ServiceTag
}

interface ServiceBalance {
  id: number
  user_id: number
  create_time: number
  expire_time: number
  remain_count: number
  request_type: ServiceTag
}

interface DigitalHumanItem {
  user_id: number
  create_time: number
  model_id: number
  avatar: string
  type: number
  name: string
  description: string
  id?: number
  digital_human_id: number
}

interface GBVideoItem {
  id: number
  user_id: number
  task_id: string
  create_time: number
  complete_time: number
  progress: number
  duration?: number
  digital_human_id: number
  title: string
  content: string
  bg_img: string
  video_url?: string
  video_cover?: string
  subtitle?: string
  speed: number
}

interface TitlesTemplate {
  id: number
  create_time: number
  opening_url: string
  opening_file: string
  ending_url: string
  ending_file: string
  type: number
  title: string
  description: string
}

interface PPTCategory {
  id: number
  type: string
  create_time: number
}

interface PPTTemplate {
  id: number
  create_time: number
  file_url: string
  preview_url: string
  title: string
  description: string
  type: string
}

// Common request and response schemas
namespace req {
  namespace user {
    /**
     * @description 用户登录
     * @param username 用户名或手机号
     * @param password 密码
     */
    interface Login {
      username: string
      password: string
    }

    interface SmsLogin {
      mobile: string
    }

    interface SmsLoginVerify {
      mobile: string
      sms_code: string
    }

    interface UserList {
      page?: number
      perpage?: number
      is_verify: boolean
    }

    interface ChangePassword {
      username: string
      old_password: string
      new_password: string
    }

    interface SmsChangePasswordVerify {
      mobile: string
    }

    interface SmsChangePassword {
      mobile: string
      sms_code: string
      new_password: string
    }
  }

  namespace file {
    interface Upload {
      file_name: string
      file_type: string
      file_size: number
    }
  }

  namespace gen {
    interface CourseGenList {
      page?: number
      perpage?: number
      to_user_id: number
    }

    /**
     * @description 创建生成任务
     * @param digital_human_id 数字人物 ID (string || number 存疑)
     */
    interface CourseGenCreate {
      digital_human_id: number
      ppt_url: string
      opening_url: string
      ending_url: string
      custom_video: string
      gen_server: 'main' | 'standby1'
      task_title: string
      speed: number
    }

    interface CourseGenDelete {
      to_user_id: number
      task_id: string
    }

    /**
     * @param sub_type    0为绿幕生成，1为PPT生成
     * @param sub_content BASE64后的ass字幕字符串
     * @param sub_ver optional 字幕版本
     */
    interface CourseSubtitleCreate {
      sub_type: 0 | 1
      task_id: string
      sub_content: string
      sub_ver?: number
    }

    interface DigitalHumanList {
      to_user_id: number
      page?: number
      perpage?: number
    }

    /**
     * @param title 任务标题筛选
     */
    interface GBVideoList {
      to_user_id: number
      page?: number
      perpage?: number
      title?: string
    }

    interface GBVideoCreate {
      device_id: string
      digital_human_id: number
      title: string
      content: string
      bg_img?: string
      speed?: number
    }

    interface GBVideoDelete {
      task_id: string
    }

    interface TitlesTemplateRequest {
      to_user_id: number
      title_id: number
      title: string
      description: string
    }
  }

  interface AssistantTemplateList {
    page: number
    perpage: number
  }
}

namespace resp {
  namespace user {
    interface CheckSession {
      is_login: boolean
    }

    interface Login {
      is_login: boolean
      token?: string
      user_id?: number
    }

    interface Profile {
      profile: UserSchema
    }

    interface SmsLogin {
      message: string
    }

    interface SmsLoginVerify {
      token: string
      person_id: number
    }
  }

  namespace gen {
    interface CourseGenItem {
      message: string
      device_id: string
      user_id: number
      task_id: string
      create_time: number
      complete_time: number
      duration: number
      video_duration: number
      token: string
      progress: number
      digital_human_id: number
      video_url: string
      subtitle_url: string
      video_cover: string
      custom_video: string
      title: string
      ppt_url: string
      opening_url: string
      ending_url: string
      speed: number
    }

    interface CourseGenCreate {
      task_id: string
      res_gen_server: 'main' | 'standby1'
      record_status: 0 | 1
    }

    interface CourseGenDelete {
      code: 0 | 1
    }

    /**
     * @param video_sub_id  字幕记录 ID
     * @param url           已上传的ass文件URL(文件存放于OSS)
     */
    interface CourseSubtitleCreate {
      video_sub_id: number
      url: string
    }

    /**
     * @param request_id  任务 ID，同 task_id
     */
    interface GBVideoCreate {
      data_id: string
      task_id: string
    }

    /**
     * @param code  1: 删除成功, 0: 删除失败
     */
    interface GBVideoDelete {
      code: 0 | 1
    }
  }
}

// Specific modals
namespace HunYuan {
  type Resolution = '768:768' | '768:1024' | '1024:768'

  interface resp {
    data_id: string | number
    request_id: string
    request_image: string
  }

  namespace Text2Img {
    interface req {
      device_id: string
      prompt: string
      negative_prompt?: string
      styles: number
      resolution: string
    }
  }

  namespace Img2Img {
    interface req {
      device_id: string
      prompt: string
      negative_prompt?: string
      styles: number
      resolution: string
      file: File
    }
  }
}
