import { defineComponent, onMounted , ref, effect} from "vue";
import { string } from "vue-types";
import { useCompData } from ".";
import { useEditor } from "../../../..";
import { View } from "../View";
import { CompUI } from "../..";
import { values } from "lodash";
import { Angle } from "@/modules/editor/controllers/SelectCtrl/objects/mathUtils";

function findNearestPoint(points: number[][], w:number, h:number, sx:number, sy:number) {
   const n = points.length;
   let minv = 100000;
    let minIndex = -1;
    const positions = []

   for(let i=0; i<n; i++) {
      const p = points[i];
      const x = w *p[0];
      const y = h *p[1];
      positions.push([x, y]);

      const ln = (sx-x)*(sx-x) + (sy-y)*(sy-y);
      if ( ln < minv ) {
        minIndex = i;
        minv = ln;
         if(!(sx < (x -10) || sx > (x + 10) || sy < (y -10) || sy > (y+10) ) ) {
            return {clicked: true, index: i};
         }
      }
   }   

   let preIndex = minIndex -1;
   if (preIndex < 0 ) preIndex = n-1;
   let afterIndex = minIndex + 1;
   if ( afterIndex >= n) afterIndex = 0;

   const currV = {x:sx-positions[minIndex][0], y:sy-positions[minIndex][1]};
   const preV = {x:positions[preIndex][0]-positions[minIndex][0], y:positions[preIndex][1]-positions[minIndex][1]}
   const afterV = {x:positions[afterIndex][0]-positions[minIndex][0], y:positions[afterIndex][1]-positions[minIndex][1]}

  const a1 =  Angle(currV, preV)
  const a2 =  Angle(currV, afterV);

  if (a1 < a2) {
    return {index: preIndex};
  }

  return {index: minIndex};
}

export const Component = defineComponent({
  props: {
    compId: string().isRequired,
  },
  setup(props) {
    const { helper, controls , store} = useEditor();
    const data = useCompData(props.compId);
    const canvasRef =  ref<HTMLCanvasElement>();
    onMounted(()=>{
        
        // draw();
        let isDragingIndex = -1;
        canvasRef.value?.addEventListener("dblclick", function(e:MouseEvent){
            
            const x = helper.pxToDesignSize(e.offsetX )
            const y = helper.pxToDesignSize(e.offsetY)
            
            const points = data.value.points as number[][];
            const w = data.layout.size[0];
            const h = data.layout.size[1];
            //判断直线相交求解点到直线的距离
            const ret = findNearestPoint(data.value.points, w , h, x, y);
            //判断是否
            console.log("dbclick=>xxxxx", ret);
            if (ret.clicked) {//点击删除
                points.splice(ret.index, 1);
                if (points.length < 4) {
                    return;
                }

            } else {
                points.splice(ret.index+1, 0, [x / w, y / h]);
            }

            draw();
        })

        canvasRef.value?.addEventListener("mousedown", function(e:MouseEvent){
                if (store.currCompId != props.compId) return;

                const el = canvasRef.value as HTMLCanvasElement;
                const x = helper.pxToDesignSize(e.offsetX )
                const y = helper.pxToDesignSize(e.offsetY)
                
                console.log(x , y);

                const points = data.value.points as number[][];
                const width = data.layout.size[0];
                const height = data.layout.size[1];

                let n = points.length;
                isDragingIndex = -1;
                let initX = 0;
                let initY = 0;

                while(n--) {
                    const p = points[n];

                    const px = width * p[0];
                    const py = height * p[1];
                    
                    if(!(x < (px -10) || x > (px + 10) || y < (py -10) || y > (py+10) ) ) {
                        isDragingIndex = n;
                        initX = p[0]
                        initY = p[1]
                        break;
                    }

                }
                
                const dragingX = x;
                const dragingY = y;

                if (isDragingIndex != -1) {
                    e.preventDefault();
                    e.stopPropagation();

                    const move =  function (e:MouseEvent){
                        if ( isDragingIndex == -1) return;
                         
                        const offx = (helper.pxToDesignSize(e.offsetX ) - dragingX) / width;
                        const offy = (helper.pxToDesignSize(e.offsetY ) -  dragingY) / height;

                        points[isDragingIndex][0] = initX + offx;
                        points[isDragingIndex][1] = initY + offy;

                        draw();
                    }

                    el.addEventListener("mousemove", move)

                    el.addEventListener("mouseup", function(e:MouseEvent){
                        el.removeEventListener("mousemove", move);
                    });

                    el.addEventListener("mouseleave", function(e:MouseEvent){
                        el.removeEventListener("mousemove", move);
                    })


                }
        }, )

       
        effect(draw);
    })

    

   
    function draw() {
        const canvas = canvasRef.value as HTMLCanvasElement;
        if (!canvas) return;

        const ctx = canvasRef.value?.getContext("2d") as CanvasRenderingContext2D;

        const width = data.layout.size[0];
        const height = data.layout.size[1];
        canvas.width = Math.ceil(Math.max(1, width));
        canvas.height = Math.ceil(Math.max(1, height));
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.lineWidth = data.value.lineWidth;
        
    
        ctx.strokeStyle = data.value.lineColor;
    
        const padding = 0.2;

        ctx.lineJoin = "round";
        ctx.beginPath();
       

        let points = data.value.points as number[][];
        if (data.value.points.length == 0) {
            data.value.points = [[padding, 0.5, 0.4, 0.1], [1 - padding, 0.5, 0.4, 0.1]];
            points = data.value.points;
        }

        points.forEach((p, index)=>{
            const x = width * p[0];
            const y = height * p[1];
            if (index == 0) {
                ctx.moveTo(x, y)
            } else {
                const preIndex = index -1;
                const prep = points[preIndex];
                if (prep[2] != undefined) {
                    ctx.quadraticCurveTo( width *prep[2], height *prep[3],  x, y);
                } else {
                    ctx.lineTo(x, y);
                }
            }
        })

        if (data.value.isClose) {
            ctx.closePath();
        }

        if (data.value.lineWidth !== 0) {
            ctx.stroke();
        }

        if (data.value.isFill)    {
            let bColor = data.value.fillColor;
            if (!bColor) bColor = data.value.lineColor;
            ctx.fillStyle = bColor;
            ctx.fill();
        }

        points.forEach((p, index)=>{
            const x = width * p[0];
            const y = height * p[1];

            if (store.isEditMode  && store.currCompId == props.compId) {
                ctx.fillStyle = "red"

                ctx.beginPath();
                ctx.arc(x, y, 5,  0, Math.PI*2);
                ctx.fill();
            }
        })
    }

    return () => (
      <View compId={props.compId}>
         <canvas ref={canvasRef} style={{width:"100%", height: "100%"}}> </canvas>
      </View>
    );
  },
});
