import { BasicDanmakuData, Danmaku } from './danmaku-data'
import { DanmakuType } from './danmaku-type'

export type Duration = (danmaku: Danmaku) => number
export type BlockTypes = (DanmakuType | 'color')[]
export interface AssDanmakuData extends BasicDanmakuData {
  typeTag: string
  colorTag: string
  endTime: string
}
export interface FontStyles {
  [size: number]: string
}
export interface Resolution {
  x: number
  y: number
}

export class AssDanmaku extends Danmaku {
  typeTag: string
  colorTag: string
  endTime: string
  constructor({
    content,
    time,
    type,
    fontSize,
    color,
    typeTag,
    colorTag,
    endTime,
  }: AssDanmakuData) {
    super({
      content,
      time,
      type,
      fontSize,
      color,
    })
    this.typeTag = typeTag
    this.colorTag = colorTag
    this.endTime = endTime
  }
  text(fontStyles: FontStyles) {
    let style = fontStyles[this.fontSize]
    if (!style) {
      style = fontStyles['25']
    }
    const styleName = style.match(/Style:(.*?),/)[1].trim()
    return `Dialogue: 0,${this.time},${this.endTime},${styleName},,0,0,0,,{${this.typeTag}${this.colorTag}}${this.content}`
  }
}
export class AssDanmakuDocument {
  danmakus: AssDanmaku[]
  title: string
  fontStyles: FontStyles
  blockTypes: BlockTypes
  resolution: Resolution
  constructor(
    danmakus: AssDanmaku[],
    title: string,
    fontStyles: FontStyles,
    blockTypes: BlockTypes,
    resolution: Resolution,
  ) {
    this.danmakus = danmakus
    this.title = title
    this.fontStyles = fontStyles
    this.blockTypes = blockTypes
    this.resolution = resolution
  }
  generateAss() {
    const meta = `
[Script Info]
; Script generated by Bilibili Evolved Danmaku Converter
; https://github.com/the1812/Bilibili-Evolved/
Title: ${this.title}
ScriptType: v4.00+
PlayResX: ${this.resolution.x}
PlayResY: ${this.resolution.y}
Timer: 10.0000
WrapStyle: 2
ScaledBorderAndShadow: no

[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
${Object.values(this.fontStyles).join('\n')}

[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
                `.trim()
    return `${meta}\n${this.danmakus
      .map(it => it.text(this.fontStyles))
      .filter(it => it !== '')
      .join('\n')}`
  }
}
