import type { BarChartOptions, LineChartOptions, PieChartOptions } from 'chartist'

export const enum ShapePathFormulasKeys {
  ROUND_RECT = 'roundRect',
  ROUND_RECT_DIAGONAL = 'roundRectDiagonal',
  ROUND_RECT_SINGLE = 'roundRectSingle',
  ROUND_RECT_SAMESIDE = 'roundRectSameSide',
  CUT_RECT_DIAGONAL = 'cutRectDiagonal',
  CUT_RECT_SINGLE = 'cutRectSingle',
  CUT_RECT_SAMESIDE = 'cutRectSameSide',
  CUT_ROUND_RECT = 'cutRoundRect',
  MESSAGE = 'message',
  ROUND_MESSAGE = 'roundMessage',
  L = 'L',
  RING_RECT = 'ringRect',
  PLUS = 'plus',
  TRIANGLE = 'triangle',
  PARALLELOGRAM_LEFT = 'parallelogramLeft',
  PARALLELOGRAM_RIGHT = 'parallelogramRight',
  TRAPEZOID = 'trapezoid',
  BULLET = 'bullet',
  INDICATOR = 'indicator',
}

export const enum ElementTypes {
  TEXT = 'text',
  IMAGE = 'image',
  SHAPE = 'shape',
  LINE = 'line',
  CHART = 'chart',
  TABLE = 'table',
  LATEX = 'latex',
  VIDEO = 'video',
  AUDIO = 'audio',
}

/**
 * 元素阴影
 * 
 * h: 水平偏移量
 * 
 * v: 垂直偏移量
 * 
 * blur: 模糊程度
 * 
 * color: 阴影颜色
 */
export interface PPTElementShadow {
  h: number
  v: number
  blur: number
  color: string
}

/**
 * 元素边框
 * 
 * style?: 边框样式（实线或虚线）
 * 
 * width?: 边框宽度
 * 
 * color?: 边框颜色
 */
export interface PPTElementOutline {
  style?: 'dashed' | 'solid'
  width?: number
  color?: string
}

/**
 * 元素超链接
 * 
 * type: 链接类型（网页、幻灯片页面）
 * 
 * target: 目标地址（网页链接、幻灯片页面ID）
 */
export interface PPTElementLink {
  type: 'web' | 'slide'
  target: string
}


/**
 * 元素通用属性
 * 
 * id: 元素ID
 * 
 * left: 元素水平方向位置（距离画布左侧）
 * 
 * top: 元素垂直方向位置（距离画布顶部）
 * 
 * lock?: 锁定元素
 * 
 * groupId?: 组合ID（拥有相同组合ID的元素即为同一组合元素成员）
 * 
 * width: 元素宽度
 * 
 * height: 元素高度
 * 
 * rotate: 旋转角度
 * 
 * link?: 超链接
 * 
 * name?: 元素名
 */
interface PPTBaseElement {
  id: string
  left: number
  top: number
  lock?: boolean
  groupId?: string
  width: number
  height: number
  rotate: number
  link?: PPTElementLink
  name?: string
}


/**
 * 文本元素
 * 
 * type: 元素类型（text）
 * 
 * content: 文本内容（HTML字符串）
 * 
 * defaultFontName: 默认字体（会被文本内容中的HTML内联样式覆盖）
 * 
 * defaultColor: 默认颜色（会被文本内容中的HTML内联样式覆盖）
 * 
 * outline?: 边框
 * 
 * fill?: 填充色
 * 
 * lineHeight?: 行高（倍），默认1.5
 * 
 * wordSpace?: 字间距，默认0
 * 
 * opacity?: 不透明度，默认1
 * 
 * shadow?: 阴影
 * 
 * paragraphSpace?: 段间距，默认 5px
 * 
 * vertical?: 竖向文本
 */
export interface PPTTextElement extends PPTBaseElement {
  type: 'text'
  content: string
  defaultFontName: string
  defaultColor: string
  outline?: PPTElementOutline
  fill?: string
  lineHeight?: number
  wordSpace?: number
  opacity?: number
  shadow?: PPTElementShadow
  paragraphSpace?: number
  vertical?: boolean
}


/**
 * 图片翻转、形状翻转
 * 
 * flipH?: 水平翻转
 * 
 * flipV?: 垂直翻转
 */
export interface ImageOrShapeFlip {
  flipH?: boolean
  flipV?: boolean
}

/**
 * 图片滤镜
 * 
 * https://developer.mozilla.org/zh-CN/docs/Web/CSS/filter
 * 
 * 'blur'?: 模糊，默认0（px）
 * 
 * 'brightness'?: 亮度，默认100（%）
 * 
 * 'contrast'?: 对比度，默认100（%）
 * 
 * 'grayscale'?: 灰度，默认0（%）
 * 
 * 'saturate'?: 饱和度，默认100（%）
 * 
 * 'hue-rotate'?: 色相旋转，默认0（deg）
 * 
 * 'opacity'?: 不透明度，默认100（%）
 */
export type ImageElementFilterKeys = 'blur' | 'brightness' | 'contrast' | 'grayscale' | 'saturate' | 'hue-rotate' | 'opacity'
export interface ImageElementFilters {
  'blur'?: string
  'brightness'?: string
  'contrast'?: string
  'grayscale'?: string
  'saturate'?: string
  'hue-rotate'?: string
  'opacity'?: string
}

export type ImageClipDataRange = [[number, number], [number, number]]

/**
 * 图片裁剪
 * 
 * range: 裁剪范围，例如：[[10, 10], [90, 90]] 表示裁取原图从左上角 10%, 10% 到 90%, 90% 的范围
 * 
 * shape: 裁剪形状，见 configs/imageClip.ts CLIPPATHS 
 */
export interface ImageElementClip {
  range: ImageClipDataRange
  shape: string
}

/**
 * 图片元素
 * 
 * type: 元素类型（image）
 * 
 * fixedRatio: 固定图片宽高比例
 * 
 * src: 图片地址
 * 
 * outline?: 边框
 * 
 * filters?: 图片滤镜
 * 
 * clip?: 裁剪信息
 * 
 * flipH?: 水平翻转
 * 
 * flipV?: 垂直翻转
 * 
 * shadow?: 阴影
 */
export interface PPTImageElement extends PPTBaseElement {
  type: 'image'
  fixedRatio: boolean
  src: string
  outline?: PPTElementOutline
  filters?: ImageElementFilters
  clip?: ImageElementClip
  flipH?: boolean
  flipV?: boolean
  shadow?: PPTElementShadow
  colorMask?: string
}


/**
 * 形状渐变
 * 
 * type: 渐变类型（径向、线性）
 * 
 * color: 渐变颜色
 * 
 * rotate: 渐变角度（线性渐变）
 */
export interface ShapeGradient {
  type: 'linear' | 'radial'
  color: [string, string]
  rotate: number
}

/**
 * 形状内文本
 * 
 * content: 文本内容（HTML字符串）
 * 
 * defaultFontName: 默认字体（会被文本内容中的HTML内联样式覆盖）
 * 
 * defaultColor: 默认颜色（会被文本内容中的HTML内联样式覆盖）
 * 
 * align: 文本对齐方向（垂直方向）
 */
export interface ShapeText {
  content: string
  defaultFontName: string
  defaultColor: string
  align: 'top' | 'middle' | 'bottom'
}

/**
 * 形状元素
 * 
 * type: 元素类型（shape）
 * 
 * viewBox: SVG的viewBox属性，例如 [1000, 1000] 表示 '0 0 1000 1000'
 * 
 * path: 形状路径，SVG path 的 d 属性
 * 
 * fixedRatio: 固定形状宽高比例
 * 
 * fill: 填充，不存在渐变时生效
 * 
 * gradient?: 渐变，该属性存在时将优先作为填充
 * 
 * outline?: 边框
 * 
 * opacity?: 不透明度
 * 
 * flipH?: 水平翻转
 * 
 * flipV?: 垂直翻转
 * 
 * shadow?: 阴影
 * 
 * special?: 特殊形状（标记一些难以解析的形状，例如路径使用了 L Q C A 以外的类型，该类形状在导出后将变为图片的形式）
 * 
 * text?: 形状内文本
 * 
 * pathFormula?: 形状路径计算公式
 * 一般情况下，形状的大小变化时仅由宽高基于 viewBox 的缩放比例来调整形状，而 viewBox 本身和 path 不会变化，
 * 但也有一些形状希望能更精确的控制一些关键点的位置，此时就需要提供路径计算公式，通过在缩放时更新 viewBox 并重新计算 path 来重新绘制形状
 * 
 * keypoint?: 关键点位置百分比
 */
export interface PPTShapeElement extends PPTBaseElement {
  type: 'shape'
  viewBox: [number, number]
  path: string
  fixedRatio: boolean
  fill: string
  gradient?: ShapeGradient
  outline?: PPTElementOutline
  opacity?: number
  flipH?: boolean
  flipV?: boolean
  shadow?: PPTElementShadow
  special?: boolean
  text?: ShapeText
  pathFormula?: ShapePathFormulasKeys
  keypoint?: number
}


export type LinePoint = '' | 'arrow' | 'dot' 

/**
 * 线条元素
 * 
 * type: 元素类型（line）
 * 
 * start: 起点位置（[x, y]）
 * 
 * end: 终点位置（[x, y]）
 * 
 * style: 线条样式（实线、虚线）
 * 
 * color: 线条颜色
 * 
 * points: 端点样式（[起点样式, 终点样式]，可选：无、箭头、圆点）
 * 
 * shadow?: 阴影
 * 
 * broken?: 折线控制点位置（[x, y]）
 * 
 * curve?: 二次曲线控制点位置（[x, y]）
 * 
 * cubic?: 三次曲线控制点位置（[[x1, y1], [x2, y2]]）
 */
export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'> {
  type: 'line'
  start: [number, number]
  end: [number, number]
  style: 'solid' | 'dashed'
  color: string
  points: [LinePoint, LinePoint]
  shadow?: PPTElementShadow
  broken?: [number, number]
  curve?: [number, number]
  cubic?: [[number, number], [number, number]]
}


export type PresetChartType = 'bar' | 'horizontalBar' | 'line' | 'area' | 'scatter' | 'pie' | 'ring'
export type ChartType = 'bar' | 'line' | 'pie'
export type ChartOptions = LineChartOptions & BarChartOptions & PieChartOptions
export interface ChartData {
  labels: string[]
  legends: string[]
  series: number[][]
}

/**
 * 图表元素
 * 
 * type: 元素类型（chart）
 * 
 * fill?: 填充色
 * 
 * chartType: 图表基础类型（bar/line/pie），所有图表类型都是由这三种基本类型衍生而来
 * 
 * data: 图表数据
 * 
 * options?: 图表配置项
 * 
 * outline?: 边框
 * 
 * themeColor: 主题色
 * 
 * gridColor?: 网格&坐标颜色
 * 
 * legend?: 图例/位置
 */
export interface PPTChartElement extends PPTBaseElement {
  type: 'chart'
  fill?: string
  chartType: ChartType
  data: ChartData
  options?: ChartOptions
  outline?: PPTElementOutline
  themeColor: string[]
  gridColor?: string
  legend?: '' | 'top' | 'bottom'
}


/**
 * 表格单元格样式
 * 
 * bold?: 加粗
 * 
 * em?: 斜体
 * 
 * underline?: 下划线
 * 
 * strikethrough?: 删除线
 * 
 * color?: 字体颜色
 * 
 * backcolor?: 填充色
 * 
 * fontsize?: 字体大小
 * 
 * fontname?: 字体
 * 
 * align?: 对齐方式
 */
export interface TableCellStyle {
  bold?: boolean
  em?: boolean
  underline?: boolean
  strikethrough?: boolean
  color?: string
  backcolor?: string
  fontsize?: string
  fontname?: string
  align?: 'left' | 'center' | 'right'
}


/**
 * 表格单元格
 * 
 * id: 单元格ID
 * 
 * colspan: 合并列数
 * 
 * rowspan: 合并行数
 * 
 * text: 文字内容
 * 
 * style?: 单元格样式
 */
export interface TableCell {
  id: string
  colspan: number
  rowspan: number
  text: string
  style?: TableCellStyle
}

/**
 * 表格主题
 * 
 * color: 主题色
 * 
 * rowHeader: 标题行
 * 
 * rowFooter: 汇总行
 * 
 * colHeader: 第一列
 * 
 * colFooter: 最后一列
 */
export interface TableTheme {
  color: string
  rowHeader: boolean
  rowFooter: boolean
  colHeader: boolean
  colFooter: boolean
}

/**
 * 表格元素
 * 
 * type: 元素类型（table）
 * 
 * outline: 边框
 * 
 * theme?: 主题
 * 
 * colWidths: 列宽数组，如[30, 50, 20]表示三列宽度分别为30%, 50%, 20%
 * 
 * cellMinHeight: 单元格最小高度
 * 
 * data: 表格数据
 */
export interface PPTTableElement extends PPTBaseElement {
  type: 'table'
  outline: PPTElementOutline
  theme?: TableTheme
  colWidths: number[]
  cellMinHeight: number
  data: TableCell[][]
}


/**
 * LaTeX元素（公式）
 * 
 * type: 元素类型（latex）
 * 
 * latex: latex代码
 * 
 * path: svg path
 * 
 * color: 颜色
 * 
 * strokeWidth: 路径宽度
 * 
 * viewBox: SVG的viewBox属性
 * 
 * fixedRatio: 固定形状宽高比例
 */
export interface PPTLatexElement extends PPTBaseElement {
  type: 'latex'
  latex: string
  path: string
  color: string
  strokeWidth: number
  viewBox: [number, number]
  fixedRatio: boolean
}

/**
 * 视频元素
 * 
 * type: 元素类型（video）
 * 
 * src: 视频地址
 * 
 * autoplay: 自动播放
 * 
 * poster: 预览封面
 * 
 * ext: 视频后缀，当资源链接缺少后缀时用该字段确认资源类型
 */
export interface PPTVideoElement extends PPTBaseElement {
  type: 'video'
  src: string
  autoplay: boolean
  poster?: string
  ext?: string
}

/**
 * 音频元素
 * 
 * type: 元素类型（audio）
 * 
 * fixedRatio: 固定图标宽高比例
 * 
 * color: 图标颜色
 * 
 * loop: 循环播放
 * 
 * autoplay: 自动播放
 * 
 * src: 音频地址
 * 
 * ext: 音频后缀，当资源链接缺少后缀时用该字段确认资源类型
 */
export interface PPTAudioElement extends PPTBaseElement {
  type: 'audio'
  fixedRatio: boolean
  color: string
  loop: boolean
  autoplay: boolean
  src: string
  ext?: string
}


export type PPTElement = PPTTextElement | PPTImageElement | PPTShapeElement | PPTLineElement | PPTChartElement | PPTTableElement | PPTLatexElement | PPTVideoElement | PPTAudioElement


/**
 * 元素动画
 * 
 * id: 动画id
 * 
 * elId: 元素ID
 * 
 * effect: 动画效果
 * 
 * type: 动画类型（入场、退场、强调）
 * 
 * duration: 动画持续时间
 * 
 * trigger: 动画触发方式(click - 单击时、meantime - 与上一动画同时、auto - 上一动画之后)
 */
export interface PPTAnimation {
  id: string
  elId: string
  effect: string
  type: 'in' | 'out' | 'attention'
  duration: number
  trigger: 'click' | 'meantime' | 'auto'
}

/**
 * 幻灯片背景
 * 
 * type: 背景类型（纯色、图片、渐变）
 * 
 * color?: 背景颜色（纯色）
 * 
 * image?: 图片地址（图片）
 * 
 * imageSize?: 图片填充方式
 * 
 * gradientType?: 渐变类型（线性、径向）
 * 
 * gradientColor?: 渐变颜色
 * 
 * gradientRotate?: 渐变角度（线性）
 */
export interface SlideBackground {
  type: 'solid' | 'image' | 'gradient'
  color?: string
  image?: string
  imageSize?: 'cover' | 'contain' | 'repeat'
  gradientType?: 'linear' | 'radial'
  gradientColor?: [string, string]
  gradientRotate?: number
}


export type TurningMode = 'no' | 'fade' | 'slideX' | 'slideY' | 'random' | 'slideX3D' | 'slideY3D' | 'rotate' | 'scaleY' | 'scaleX' | 'scale' | 'scaleReverse'

/**
 * 幻灯片页面
 * 
 * id: 页面ID
 * 
 * elements: 元素集合
 * 
 * remark?: 备注
 * 
 * background?: 页面背景
 * 
 * animations?: 元素动画集合
 * 
 * turningMode?: 翻页方式
 */
export interface Slide {
  id: string
  elements: PPTElement[]
  remark?: string
  background?: SlideBackground
  animations?: PPTAnimation[]
  turningMode?: TurningMode
  pageType: number
}

/**
 * 幻灯片主题
 * 
 * backgroundColor: 页面背景颜色
 * 
 * themeColor: 主题色，用于默认创建的形状颜色等
 * 
 * fontColor: 字体颜色
 * 
 * fontName: 字体
 */
export interface SlideTheme {
  backgroundColor: string
  themeColor: string
  fontColor: string
  fontName: string
  outline: PPTElementOutline
  shadow: PPTElementShadow
}
