import CustomColorPicker from "@/components/CustomColorPicker";
import {
  BoldOutlined,
  ColumnHeightOutlined,
  FontSizeOutlined,
  ItalicOutlined,
  PictureOutlined,
  StrikethroughOutlined,
  SwapOutlined,
  UnderlineOutlined,
  VerticalAlignBottomOutlined,
  VerticalAlignMiddleOutlined,
  VerticalAlignTopOutlined,
} from "@ant-design/icons";
import {
  Button,
  Col,
  Divider,
  Form,
  Input,
  InputNumber,
  Row,
  Select,
  Tooltip,
} from "antd";
import { arrowOptions } from "@/pages/flow/data";
import { useModel } from "umi";
import { useEffect, useRef, useState } from "react";
import { ImageFillType, ConnectorType, LineType } from "@/enum";
import { set, cloneDeep } from "lodash-es";
import { Cell } from "@antv/x6";
import { fontFamilyOptions, alignOptionData } from '@/pages/flow/data';
import { alignCell, matchSize } from '@/utils';
import { cellStyle } from '@/types'

type FormModel = {
  opacity: number;
  width: number;
  height: number;
  x: number;
  y: number;
  rotation: number;
  connectorType: ConnectorType;
  startArrow: string;
  endArrow: string;
} & cellStyle;
export default function GraphStyle() {
  const { selectedCell } = useModel("graphModel");
  const [isMulit, setIsMulit] = useState(false);
  const [hasEdge, setHasEdge] = useState(false);
  const eventNodeList = useRef<Cell[]>([]);

  const [formModel, setFormModel] = useState<FormModel>({
    opacity: 100,
    width: 20,
    height: 20,
    x: 0,
    y: 0,
    rotation: 0,
    text: {
      fontFamily: "normal",
      color: "#000000",
      fontSize: 14,
      lineHeight: 1.25,
      textAlign: "center",
      textVAlign: "middle",
      bold: false,
      italic: false,
      textDecoration: "none",
    },
    fill: {
      fillType: "color",
      color1: "#FFFFFF",
      color2: "#eeeeee",
      gradientType: "linear",
      gradientValue: 0,
      objectFit: ImageFillType.Fill,
      imageUrl: "",
    },
    stroke: {
      type: "solid",
      color: "#323232",
      width: 1,
    },
    connectorType: ConnectorType.Normal,
    startArrow: "",
    endArrow: "",
  });

  useEffect(() => {
    const firstNode = selectedCell?.find((item) => item.isNode());
    const firstEdge = selectedCell?.find((item) => item.isEdge());
    eventNodeList.current = [];
    if (firstNode) {
      const position = firstNode.position();
      const size = firstNode.size();
      const data = firstNode.getData();
      setFormModel({
        ...formModel,
        x: position.x,
        y: position.y,
        width: size.width,
        height: size.height,
        rotation: firstNode.angle(),
        text: data.text,
        fill: data.fill,
        stroke: data.stroke,
        connectorType: ConnectorType.Normal,
        startArrow: "",
        endArrow: "",
      });

      // 监听当前选中节点的属性变化
      if (!eventNodeList.current.find((item) => item.id === firstNode.id)) {
        eventNodeList.current.push(firstNode);
        firstNode.on("change:*", (args) => {
          if (args.key === "position") {
            setFormModel((state) => {
              return {
                ...state,
                x: parseInt(args.current.x),
                y: parseInt(args.current.y),
              };
            });
          }
          if (args.key === "size") {
            setFormModel((state) => {
              return {
                ...state,
                width: args.current.width,
                height: args.current.height,
              };
            });
          }
          if (args.key === "data") {
            setFormModel((state) => {
              return {
                ...state,
                text: args.current.text,
                fill: args.current.fill,
                stroke: args.current.stroke,
              };
            });
          }
        });
      }
    }

    if(firstEdge) {
      const data = firstEdge.getData();
      const attrs = firstEdge.attrs || {};
      const sourceMarker = attrs.line?.sourceMarker as Record<string, any>;
      const targetMarker = attrs.line?.targetMarker as Record<string, any>;
      const lineType = attrs.line?.strokeDasharray === LineType.solid 
        ? "solid"
        : attrs.line?.strokeDasharray === LineType.dashed
        ? "dashed"
        : attrs.line?.strokeDasharray === LineType.dotted
        ? "dotted"
        : "dashdot";
      let obj = {};
      if(!firstNode) {
        obj = {
          stroke: {
            type: lineType,
            color: attrs.line?.stroke || "#000000",
            width: attrs.line?.strokeWidth || 1,
          }
        }
      }
      setFormModel((state) => {
        return {
          ...state,
          ...obj,
          startArrow: sourceMarker?.name,
          endArrow: targetMarker?.name,
        }
      })
    }

    let nodeCount = 0;
    selectedCell?.forEach((cell) => {
      if (cell.isEdge()) {
        // 存在边线
        setHasEdge(true);
      }
      if (cell.isNode()) nodeCount++;
    });
    // 多个节点
    setIsMulit(nodeCount > 1);
  }, [selectedCell]);

  // 表单值改变，修改元素属性
  const handleChange = (model: FormModel) => {
    selectedCell?.forEach((cell) => {
      if (cell.isNode()) {
        cell.setPosition(model.x, model.y);
        cell.setSize(model.width, model.height);
        cell.rotate(model.rotation, { absolute: true });
        cell.setData({
          text: model.text,
          fill: model.fill,
          stroke: model.stroke,
          opacity: model.opacity,
        });
      }
      if (cell.isEdge()) {
        const attr = cell.attrs;
        const sourceMarker = attr?.line?.sourceMarker as Record<string, any>;
        const targetMarker = attr?.line?.targetMarker as Record<string, any>;
        cell.setAttrs({
          line: {
            ...(attr?.line || {}),
            stroke: model.stroke.color,
            strokeWidth: model.stroke.width,
            strokeDasharray: LineType[model.stroke.type],
            targetMarker: {
              ...(targetMarker || {}),
              name: model.endArrow,
              args: {
                size: model.stroke.width + 8,
              }
            },
            sourceMarker: {
              ...(sourceMarker || {}),
              name: model.startArrow,
              args: {
                size: model.stroke.width + 8,
              }
            }
          }
        })
      }
    });
  };

  // 设置对齐方式
  const handleAlign = (type: "left" | "hcenter" | "right" | "top" | "vcenter" | "bottom" | "h" | "v") => {
    selectedCell && alignCell(type, selectedCell);
  };

  // 匹配宽高
  const handleMatchSize = (type: "width" | "height" | "auto") => {
    selectedCell && matchSize(type, selectedCell);
  };

  // 调换渐变色颜色
  const handleSwapColor = () => {
    const { color1, color2 } = formModel.fill;
    handleSetFormModel("fill", {
      ...formModel.fill,
      color1: color2,
      color2: color1,
    });
  };

  // 设置表单数据
  const handleSetFormModel = (key: string, value: any) => {
    const obj = cloneDeep(formModel);
    set(obj, key, value);
    setFormModel(obj);
    handleChange(obj);
  };

  return (
    <div>
      <section className="px-16px">
        <div className="bg-white rounded-s flex justify-between items-center mb-8px">
          {alignOptionData.map((item) => (
            <Tooltip key={item.id} title={item.name}>
              <Button
                type="text"
                icon={<i className={"iconfont " + item.icon} />}
                disabled={!isMulit}
                onClick={() => handleAlign(item.id)}
              />
            </Tooltip>
          ))}
        </div>
        <Form.Item
          label="不透明度"
          labelCol={{ span: 14 }}
          wrapperCol={{ span: 10 }}
          labelAlign="left"
          className="mb-8px"
          colon={false}
        >
          <InputNumber
            className="w-full"
            step={5}
            min={0}
            max={100}
            formatter={(val) => `${val}%`}
            disabled={!selectedCell?.length}
            value={formModel.opacity}
            onChange={(val) => handleSetFormModel("opacity", val)}
          />
        </Form.Item>
      </section>
      <Divider className="my-8px" />
      <section className="px-16px">
        <div className="font-bold mb-8px">布局</div>
        <Row gutter={8} className="mb-8px">
          <Col span={12}>
            <InputNumber
              className="w-full"
              step={1}
              min={20}
              max={10000}
              suffix="W"
              formatter={(val) => `${val}px`}
              disabled={!selectedCell?.length}
              value={formModel.width}
              onChange={(val) => handleSetFormModel("width", val)}
            />
          </Col>
          <Col span={12}>
            <InputNumber
              className="w-full"
              step={1}
              min={20}
              max={10000}
              suffix="H"
              formatter={(val) => `${val}px`}
              disabled={!selectedCell?.length}
              value={formModel.height}
              onChange={(val) => handleSetFormModel("height", val)}
            />
          </Col>
        </Row>
        <Row gutter={8} className="mb-8px">
          <Col span={12}>
            <InputNumber
              className="w-full"
              step={1}
              min={0}
              max={10000}
              precision={0}
              suffix="X"
              formatter={(val) => `${val}px`}
              disabled={!selectedCell?.length}
              value={formModel.x}
              onChange={(val) => handleSetFormModel("x", val)}
            />
          </Col>
          <Col span={12}>
            <InputNumber
              className="w-full"
              step={1}
              min={0}
              max={10000}
              precision={0}
              suffix="Y"
              formatter={(val) => `${val}px`}
              disabled={!selectedCell?.length}
              value={formModel.y}
              onChange={(val) => handleSetFormModel("y", val)}
            />
          </Col>
        </Row>
        <div className="flex justify-between items-center gap-12px mb-8px">
          <InputNumber
            className="flex-1"
            step={1}
            min={0}
            max={360}
            formatter={(val) => `${val}°`}
            suffix={<i className="iconfont icon-a-ziyuan126 text-12px" />}
            disabled={!selectedCell?.length}
            value={formModel.rotation}
            onChange={(val) => handleSetFormModel("rotation", val)}
          />
          <Button
            icon={<i className="iconfont icon-shangxiafanzhuan" />}
            disabled={!selectedCell?.length}
            onClick={() => handleSetFormModel("rotation", 0)}
          />
          <Button
            icon={<i className="iconfont icon-zuoyoufanzhuan" />}
            disabled={!selectedCell?.length}
            onClick={() => handleSetFormModel("rotation", 90)}
          />
        </div>
        <Form.Item
          label="匹配大小"
          labelCol={{ span: 14 }}
          wrapperCol={{ span: 10 }}
          labelAlign="left"
          className="mb-8px"
          colon={false}
        >
          <div className="bg-white rounded-s flex justify-between items-center mb-8px">
            <Tooltip title="适配宽度">
              <Button
                type="text"
                icon={<i className="iconfont icon-kuandu" />}
                disabled={!isMulit}
                onClick={() => handleMatchSize("width")}
              />
            </Tooltip>
            <Tooltip title="适配高度">
              <Button
                type="text"
                icon={<i className="iconfont icon-gaodu" />}
                disabled={!isMulit}
                onClick={() => handleMatchSize("height")}
              />
            </Tooltip>
            <Tooltip title="适配宽高">
              <Button
                type="text"
                icon={<i className="iconfont icon-shiyingkuangao" />}
                disabled={!isMulit}
                onClick={() => handleMatchSize("auto")}
              />
            </Tooltip>
          </div>
        </Form.Item>
      </section>
      <Divider className="my-8px" />
      <section className="px-16px">
        <div className="font-bold mb-8px">文本</div>
        <div className="flex items-center  gap-12px mb-8px">
          <Select
            className="flex-1"
            disabled={!selectedCell?.length}
            options={fontFamilyOptions}
            value={formModel.text.fontFamily}
            labelRender={(item) => item.value}
            onChange={(val) => handleSetFormModel("text.fontFamily", val)}
          />
          <CustomColorPicker
            disabled={!selectedCell?.length}
            color={formModel.text.color}
            onChange={(color) => handleSetFormModel("text.color", color)}
          />
        </div>
        <div className="flex items-center gap-12px mb-8px">
          <InputNumber
            className="flex-1"
            prefix={<FontSizeOutlined />}
            step={1}
            min={12}
            max={10000}
            formatter={(val) => `${val}px`}
            disabled={!selectedCell?.length}
            value={formModel.text.fontSize}
            onChange={(val) => handleSetFormModel("text.fontSize", val)}
          />
          <Select
            className="flex-1"
            suffixIcon={<ColumnHeightOutlined />}
            options={[
              { label: "1.0", value: 1 },
              { label: "1.25", value: 1.25 },
              { label: "1.5", value: 1.5 },
              { label: "2.0", value: 2 },
              { label: "2.5", value: 2.5 },
              { label: "3.0", value: 3 },
            ]}
            disabled={!selectedCell?.length}
            value={formModel.text.lineHeight}
            onChange={(val) => handleSetFormModel("text.lineHeight", val)}
          />
        </div>
        <div className="flex items-center gap-12px mb-8px">
          <div className="bg-white rounded-s flex justify-between items-center mb-8px">
            <Tooltip title="左对齐">
              <Button
                type="text"
                icon={<i className="iconfont icon-zuoduiqi" />}
                className={formModel.text.textAlign === "left" ? "active" : ""}
                disabled={!selectedCell?.length}
                onClick={() => handleSetFormModel("text.textAlign", "left")}
              />
            </Tooltip>
            <Tooltip title="居中">
              <Button
                type="text"
                icon={<i className="iconfont icon-juzhong" />}
                className={
                  formModel.text.textAlign === "center" ? "active" : ""
                }
                disabled={!selectedCell?.length}
                onClick={() => handleSetFormModel("text.textAlign", "center")}
              />
            </Tooltip>
            <Tooltip title="右对齐">
              <Button
                type="text"
                icon={<i className="iconfont icon-youduiqi" />}
                className={formModel.text.textAlign === "right" ? "active" : ""}
                disabled={!selectedCell?.length}
                onClick={() => handleSetFormModel("text.textAlign", "right")}
              />
            </Tooltip>
          </div>
          <div className="bg-white rounded-s flex justify-between items-center mb-8px">
            <Tooltip title="顶部对齐">
              <Button
                type="text"
                icon={<VerticalAlignTopOutlined />}
                disabled={!selectedCell?.length}
                className={formModel.text.textVAlign === "top" ? "active" : ""}
                onClick={() => handleSetFormModel("text.textVAlign", "top")}
              />
            </Tooltip>
            <Tooltip title="垂直居中">
              <Button
                type="text"
                icon={<VerticalAlignMiddleOutlined />}
                className={
                  formModel.text.textVAlign === "middle" ? "active" : ""
                }
                disabled={!selectedCell?.length}
                onClick={() => handleSetFormModel("text.textVAlign", "middle")}
              />
            </Tooltip>
            <Tooltip title="底部对齐">
              <Button
                type="text"
                icon={<VerticalAlignBottomOutlined />}
                className={
                  formModel.text.textVAlign === "bottom" ? "active" : ""
                }
                disabled={!selectedCell?.length}
                onClick={() => handleSetFormModel("text.textVAlign", "bottom")}
              />
            </Tooltip>
          </div>
        </div>
        <div className="flex items-center gap-12px mb-8px">
          <div className="bg-white rounded-s flex justify-between items-center mb-8px">
            <Tooltip placement="bottom" title="字体加粗">
              <Button
                type="text"
                icon={<BoldOutlined />}
                className={formModel.text.bold ? "active" : ""}
                disabled={!selectedCell?.length}
                onClick={() =>
                  handleSetFormModel("text.bold", !formModel.text.bold)
                }
              />
            </Tooltip>
            <Tooltip placement="bottom" title="字体倾斜">
              <Button
                type="text"
                icon={<ItalicOutlined />}
                className={formModel.text.italic ? "active" : ""}
                disabled={!selectedCell?.length}
                onClick={() =>
                  handleSetFormModel("text.italic", !formModel.text.italic)
                }
              />
            </Tooltip>
            <Tooltip placement="bottom" title="下划线">
              <Button
                type="text"
                icon={<UnderlineOutlined />}
                className={
                  formModel.text.textDecoration === "underline" ? "active" : ""
                }
                disabled={!selectedCell?.length}
                onClick={() =>
                  handleSetFormModel(
                    "text.textDecoration",
                    formModel.text.textDecoration === "underline"
                      ? "none"
                      : "underline"
                  )
                }
              />
            </Tooltip>
            <Tooltip placement="bottom" title="中划线">
              <Button
                type="text"
                icon={<StrikethroughOutlined />}
                className={
                  formModel.text.textDecoration === "line-through"
                    ? "active"
                    : ""
                }
                disabled={!selectedCell?.length}
                onClick={() =>
                  handleSetFormModel(
                    "text.textDecoration",
                    formModel.text.textDecoration === "line-through"
                      ? "none"
                      : "line-through"
                  )
                }
              />
            </Tooltip>
          </div>
        </div>
      </section>
      <Divider className="my-8px" />
      <section className="px-16px">
        <div className="font-bold mb-8px">填充</div>
        <div className="flex items-center gap-12px mb-8px">
          <Select
            className="flex-1"
            options={[
              { label: "纯色", value: "color" },
              { label: "渐变", value: "gradient" },
              { label: "图片", value: "image" },
            ]}
            disabled={!selectedCell?.length}
            value={formModel.fill.fillType}
            onChange={(value) => handleSetFormModel("fill.fillType", value)}
          />
          <div className="flex items-center gap-12px">
            <CustomColorPicker
              disabled={!selectedCell?.length}
              color={formModel.fill.color1}
              onChange={(color) => handleSetFormModel("fill.color1", color)}
            />
            {formModel.fill.fillType === "gradient" && (
              <>
                <Button
                  icon={<SwapOutlined />}
                  disabled={!selectedCell?.length}
                  onClick={handleSwapColor}
                />
                <CustomColorPicker
                  disabled={!selectedCell?.length}
                  color={formModel.fill.color2}
                  onChange={(color) => handleSetFormModel("fill.color2", color)}
                />
              </>
            )}
          </div>
        </div>
        {formModel.fill.fillType === "image" && (
          <>
            <Form.Item
              label="图片地址"
              labelCol={{ span: 14 }}
              wrapperCol={{ span: 10 }}
              labelAlign="left"
              className="mb-8px"
              colon={false}
            >
              <Input
                placeholder="图片地址"
                disabled={!selectedCell?.length}
                suffix={<PictureOutlined />}
                value={formModel.fill.imageUrl}
                onChange={(e) =>
                  handleSetFormModel("fill.imageUrl", e.target.value)
                }
              />
            </Form.Item>
            <Form.Item
              label="填充方式"
              labelCol={{ span: 14 }}
              wrapperCol={{ span: 10 }}
              labelAlign="left"
              className="mb-8px"
              colon={false}
            >
              <Select
                options={[
                  { value: ImageFillType.Fill, label: "填充" },
                  { value: ImageFillType.Auto, label: "自适应" },
                  { value: ImageFillType.Stretch, label: "按图形伸展" },
                  { value: ImageFillType.Original, label: "原始尺寸" },
                  { value: ImageFillType.Tiled, label: "平铺" },
                ]}
                disabled={!selectedCell?.length}
                value={formModel.fill.objectFit}
                onChange={(value) =>
                  handleSetFormModel("fill.objectFit", value)
                }
              />
            </Form.Item>
          </>
        )}
        {formModel.fill.fillType === "gradient" && (
          <div className="flex items-center gap-12px">
            <Select
              className="flex-1"
              options={[
                { value: "linear", label: "线性渐变" },
                { value: "radial", label: "径向渐变" },
              ]}
              disabled={!selectedCell?.length}
              value={formModel.fill.gradientType}
              onChange={(value) => {
                handleSetFormModel("fill.gradientType", value);
              }}
            />
            {formModel.fill.fillType === "gradient" && (
              <>
                {formModel.fill.gradientType === "linear" && (
                  <InputNumber
                    className="flex-1"
                    step={1}
                    min={0}
                    max={360}
                    formatter={(val) => `${val}°`}
                    suffix={
                      <i className="iconfont icon-a-ziyuan126 text-12px" />
                    }
                    disabled={!selectedCell?.length}
                    value={formModel.fill.gradientValue}
                    onChange={(val) =>
                      handleSetFormModel("fill.gradientValue", val)
                    }
                  />
                )}
                {formModel.fill.gradientType === "radial" && (
                  <InputNumber
                    className="flex-1"
                    step={1}
                    min={0}
                    max={100}
                    formatter={(val) => `${val}%`}
                    suffix={
                      <i className="iconfont icon-jingxiangjianbian text-12px" />
                    }
                    disabled={!selectedCell?.length}
                    value={formModel.fill.gradientValue}
                    onChange={(val) =>
                      handleSetFormModel("fill.gradientValue", val)
                    }
                  />
                )}
              </>
            )}
          </div>
        )}
      </section>
      <Divider className="my-8px" />
      <section className="px-16px">
        <div className="font-bold mb-8px">线条</div>
        <div className="flex gap-12px mb-8px">
          <Select
            className="flex-1"
            options={[
              { label: "实线", value: "solid" },
              { label: "虚线", value: "dashed" },
              { label: "点线", value: "dotted" },
              { label: "点划线", value: "dashdot" },
            ]}
            disabled={!selectedCell?.length}
            value={formModel.stroke.type}
            onChange={(value) => handleSetFormModel("stroke.type", value)}
          />
          <CustomColorPicker
            disabled={!selectedCell?.length}
            color={formModel.stroke.color}
            onChange={(color) => handleSetFormModel("stroke.color", color)}
          />
        </div>
        <div className="flex gap-12px mb-8px">
          <InputNumber
            className="flex-1"
            step={1}
            min={1}
            max={10}
            formatter={(val) => `${val}px`}
            disabled={!selectedCell?.length}
            value={formModel.stroke.width}
            onChange={(val) => handleSetFormModel("stroke.width", val)}
          />
          <div className="bg-white rounded-s flex justify-between items-center">
            <Button
              type="text"
              icon={
                <i className="iconfont icon-a-icon16lianxianleixinghuizhilianxian" />
              }
              className={
                formModel.connectorType === ConnectorType.Rounded
                  ? "active"
                  : ""
              }
              disabled={!hasEdge}
              onClick={() =>
                handleSetFormModel("connectorType", ConnectorType.Rounded)
              }
            />
            <Button
              type="text"
              icon={
                <i className="iconfont icon-a-icon16lianxianleixingbeisaierquxian" />
              }
              className={
                formModel.connectorType === ConnectorType.Smooth ? "active" : ""
              }
              disabled={!hasEdge}
              onClick={() =>
                handleSetFormModel("connectorType", ConnectorType.Smooth)
              }
            />
            <Button
              type="text"
              icon={
                <i className="iconfont icon-a-icon16lianxianleixinghuizhizhixian" />
              }
              className={
                formModel.connectorType === ConnectorType.Normal ? "active" : ""
              }
              disabled={!hasEdge}
              onClick={() =>
                handleSetFormModel("connectorType", ConnectorType.Normal)
              }
            />
          </div>
        </div>
        <Form.Item
          label="箭头类型"
          labelAlign="left"
          colon={false}
          labelCol={{ span: 6 }}
          wrapperCol={{ span: 18 }}
        >
          <div className="flex gap-12px items-center">
            <Select
              options={arrowOptions.map((item) => {
                return {
                  value: item.name,
                  label: <img className="w-12px mx-50%" src={item.icon} />,
                };
              })}
              disabled={!hasEdge}
              value={formModel.startArrow}
              onChange={(value) => handleSetFormModel("startArrow", value)}
            />
            <Select
              options={arrowOptions.map((item) => {
                return {
                  value: item.name,
                  label: <img className="w-12px mx-50%" src={item.icon} />,
                };
              })}
              disabled={!hasEdge}
              value={formModel.endArrow}
              onChange={(value) => handleSetFormModel("endArrow", value)}
            />
          </div>
        </Form.Item>
      </section>
    </div>
  );
}
