<template>
  <div class="cap-wrap" @click="refresh" :title="'点击刷新验证码'">
    <canvas ref="cv"></canvas>
  </div>
</template>

<script>
export default {
  name: "CaptchaCanvas",
  props: { value: String },
  data() { return { code: "" }; },
  mounted() {
    this.refresh();
    if (typeof ResizeObserver !== "undefined") {
      this.ro = new ResizeObserver(() => this.draw());
      this.ro.observe(this.$el);
    }
  },
  beforeDestroy() {
    if (this.ro) { this.ro.disconnect(); this.ro = null; }
  },
  methods: {
    randChar() {
      const chars = "ABCDEFGHJKLMNPQRSTUVWXYZ23456789";
      return chars[Math.floor(Math.random() * chars.length)];
    },
    refresh() {
      this.code = Array.from({ length: 4 }).map(() => this.randChar()).join("");
      this.$emit("input", this.code);
      this.draw();
    },
    draw() {
      const cv = this.$refs.cv;
      if (!cv) return;
      const wrap = this.$el;
      const w = wrap.clientWidth || 120;
      const h = wrap.clientHeight || 60;
      const dpr = window.devicePixelRatio || 1;
      cv.width = Math.round(w * dpr);
      cv.height = Math.round(h * dpr);
      cv.style.width = w + "px";
      cv.style.height = h + "px";
      const ctx = cv.getContext("2d");
      ctx.setTransform(dpr, 0, 0, dpr, 0, 0);

      // 背景
      ctx.clearRect(0, 0, w, h);
      const g = ctx.createLinearGradient(0, 0, w, h);
      g.addColorStop(0, "rgba(14,45,120,0.65)");
      g.addColorStop(1, "rgba(8,20,55,0.85)");
      ctx.fillStyle = g;
      ctx.fillRect(0, 0, w, h);

      // 干扰线
      for (let i = 0; i < 5; i++) {
        ctx.strokeStyle = `rgba(60,180,255,${0.15 + Math.random() * 0.25})`;
        ctx.beginPath();
        ctx.moveTo(Math.random() * w, Math.random() * h);
        ctx.lineTo(Math.random() * w, Math.random() * h);
        ctx.stroke();
      }

      // 字符：按容器宽高等分布点 + 字号随高度缩放
      const n = this.code.length;
      const fontSize = Math.max(12, Math.round(h * 0.55));
      ctx.font = `bold ${fontSize}px Arial`;
      ctx.textBaseline = "middle";
      ctx.textAlign = "center";
      for (let i = 0; i < n; i++) {
        const x = (w * (i + 0.5)) / n;
        const y = h / 2 + (Math.random() * 6 - 4);
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(((Math.random() * 14 - 7) * Math.PI) / 180);
        ctx.fillStyle = "rgba(210,245,255,0.92)";
        ctx.fillText(this.code[i], 0, 0);
        ctx.restore();
      }
    }
  }
};
</script>

<style scoped>
.cap-wrap {
  width: 100%;
  height: 100%;
  border: 1px solid #3D6EB8;
  border-radius: 8px;
  overflow: hidden;
  cursor: pointer;
  box-sizing: border-box;
}
canvas { display: block; }
</style>
