<template>
  <canvas 
    :id="id"
    :canvas-id="id"
    :class="[
      'nana-watermark',
      {'nana-watermark-full-page': props.fullPage}
    ]"
    :style="style"
    :width="`${measuredWidth}px`"
    :height="`${measuredHeight}px`"
  />
</template>

<script setup lang="ts">
import { computed, getCurrentInstance, nextTick, onMounted, ref, watch } from 'vue';
import { propGetThemeVar, useTheme } from '../theme/ThemeDefine';
import { RandomUtils } from '@imengyu/imengyu-utils';

export interface WatermarkProps {
  /**
   * 水印组件宽度(px)。默认占满父容器
   */
  width?: number,
  /**
   * 水印组件高度(px)。默认占满父容器
   */
  height?: number,
  /**
   * 水印文字字体
   * @default '14px sans-serif'
   */
  contentFont?: string,
  /**
   * 水印文字宽度
   * @default 100
   */
  contentWidth?: number,
  /**
   * 水印文字高度
   * @default 100
   */
  contentHeight?: number,
  /**
   * 水印文字水平间距(px)
   * @default 10
   */
  offsetX?: number,
  /**
   * 水印文字垂直间距(px)
   * @default 10
   */
  offsetY?: number,
  /**
   * 水印组件z-index
   * @default 999
   */
  zIndex?: number | string,
  /**
   * 水印内容
   */
  content?: string,
  /**
   * 水印字体颜色
   * @default 'text.second'
   */
  contentColor?: string,
  /**
   * 水印图片
   * @remark 小程序似乎不能使用本地图片，需要使用网络图片地址。
   */
  image?: string,
  /**
   * 水印旋转角度(deg)
   * @default -22
   */
  rotate?: number,
  /**
   * 水印组件是否全屏
   */
  fullPage?: boolean,
  /**
   * 水印组件水平间距(px)
   * @default 10
   */
  gapX?: number,
  /**
   * 水印组件垂直间距(px)
   * @default 10
   */
  gapY?: number,
  /**
   * 水印透明度
   * @default 0.8
   */
  opacity?: number,
}

const id = `watermarkCanvas${RandomUtils.genNonDuplicateID(10)}`;
const instance = getCurrentInstance();
const props = withDefaults(defineProps<WatermarkProps>(), {
  zIndex: 999,
  content: '',
  contentFont: () => propGetThemeVar('WatermarkContentFont', '14px Arial'),
  contentWidth: () => propGetThemeVar('WatermarkContentWidth', 100),
  contentHeight: () => propGetThemeVar('WatermarkContentHeight', 60),
  image: '',
  rotate: () => propGetThemeVar('WatermarkRotate', -22),
  fullPage: false,
  offsetX: 0,
  offsetY: 0,
  gapX: () => propGetThemeVar('WatermarkGapX', 30),
  gapY: () => propGetThemeVar('WatermarkGapY', 40),
  contentColor: () => propGetThemeVar('WatermarkTextColor', 'text.second'),
  opacity: () => propGetThemeVar('WatermarkOpacity', 0.4),
});

const measuredWidth = ref(0);
const measuredHeight = ref(0);

const theme = useTheme();
const style = computed(() => ({
  width: measuredWidth.value ? `${measuredWidth.value}px` : undefined,
  height: measuredHeight.value ? `${measuredHeight.value}px` : undefined,
  zIndex: props.zIndex,
  opacity: props.opacity,
}));

const ctx = uni.createCanvasContext(id, instance);

async function drawWatermark() {

  // 设置 canvas 的尺寸为单个水印的尺寸
  const w = props.contentWidth;
  const h = props.contentHeight;
  const ch = h + props.gapY;
  const cw = w + props.gapX;

  let vh = props.height!;
  let vw = props.width!;

  await nextTick();
  await new Promise<void>((resolve) => {
    if (!vh || !vw) {
      uni.createSelectorQuery()
        // #ifndef H5
        .in(instance)
        // #endif
        .select(`#${id}`)
        .boundingClientRect().exec((res) => {
          if (res[0]) {
            if (!vh)
              vh = res[0].height;
            if (!vw)
              vw = res[0].width;
          }
          resolve();
        });
    }
  });

  measuredWidth.value = vw;
  measuredHeight.value = vh;

  // 清除 canvas
  ctx.clearRect(0, 0, vw, vh);

  if (props.image) {
    // --- 绘制图片水印 ---
    await new Promise<void>((resolve) => {
      console.log(props.image);
      
      uni.getImageInfo({
        src: props.image,
        success(res) {
          for (let i = props.offsetX; i <= vw; i += cw) {
            for (let j = props.offsetY; j <= vh; j += ch) {
              ctx.save();
              ctx.translate(i + w / 2, j + h / 2);
              ctx.rotate(props.rotate * Math.PI / 180);
              ctx.drawImage(res.path, -w / 2, -h / 2, w, res.height / res.width * w);
              ctx.restore();
            }
          }
          ctx.draw();
          resolve();
        },
        fail:(fail)=>{
          console.error('绘制水印图片失败', fail);
          resolve();
        },

      });
    }); 
  } else if (props.content) {
    ctx.setTextAlign('center');
    ctx.setTextBaseline('middle');
    ctx.setFillStyle(theme.resolveThemeColor(props.contentColor)!);
    ctx.font = props.contentFont;  

    for (let i = props.offsetX; i < vw; i += cw) {
      for (let j = props.offsetY; j < vh; j += ch) {
        ctx.save();
        ctx.translate(i + w / 2, j + h / 2);
        ctx.rotate(props.rotate * Math.PI / 180);
        ctx.fillText(props.content, 0, 0, w);
        ctx.restore();
      }
    }
    ctx.draw();
  }
}
watch(() => [
  props.content,
  props.contentWidth,
  props.contentHeight,
  props.gapX,
  props.gapY,
  props.rotate,
  props.contentColor,
], () => {
  drawWatermark();
});
onMounted(() => {
  drawWatermark();
});
</script>

<style>
.nana-watermark {
  position: absolute;
  pointer-events: none;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
}
.nana-watermark-full-page {
  position: fixed;
}
</style>