import { TreeToolbars } from "@/modules/editor/objects/Toolbars";
import { css } from "@linaria/core";
import { useReactive } from "@queenjs/use";
import { Tree } from "ant-design-vue";
import { defineComponent } from "vue";
import { string } from "vue-types";
import { useEditor } from "../../../..";
import { DesignComp } from "../../../../objects/DesignTemp/DesignComp";

type TreeItem = {
  key: string;
  title: string;
  value: string;
  children: TreeItem[];
};

export const CompTree = defineComponent({
  setup() {
    const { store, actions, helper, controls } = useEditor();
    const { compUICtrl } = controls;
    const state = useReactive(() => ({
      expandedKeys() {
        const comps = helper.getCompTrees(store.currCompId);
        return comps.map((comp) => comp.id);
      },
      treeData() {
        const rootComp = helper.findRootComp();
        function getCompChildren(ids: string[]): TreeItem[] {
          return ids.map((id) => {
            const comp = helper.findComp(id) as DesignComp;
            return {
              key: comp.id,
              title:
                compUICtrl.state.components.get(comp.compKey)?.name || "未命名",
              value: comp.id,
              children: getCompChildren(comp.getChildIds()),
            };
          });
        }
        return getCompChildren(rootComp?.id ? [rootComp.id] : []);
      },
    }));

    return () => (
      <Tree
        class={treeStyle}
        treeData={state.treeData}
        expandedKeys={state.expandedKeys}
        selectedKeys={[store.currCompId]}
        blockNode={true}
        onSelect={(ids) =>
          actions.pickComp(
            (ids[0] as string) || state.expandedKeys.at(-2) || "root"
          )
        }
      >
        {{
          title: (data: any) => {
            return <CompNode title={data.title} id={data.key} />;
          },
        }}
      </Tree>
    );
  },
});

const CompNode = defineComponent({
  props: {
    id: string().isRequired,
    title: string().isRequired,
  },
  setup(props) {
    const editor = useEditor();
    const comp = editor.helper.findComp(props.id);
    return () => {
      if (!comp) return;
      const compOpts = editor.controls.compUICtrl.state.components.get(
        comp.compKey
      );
      const actions = TreeToolbars[comp.compKey] || TreeToolbars.default;
      const thumbnail =
        comp.compKey === "Image" ? comp.value.url : compOpts?.thumbnail;
      return (
        <div class={nodeStyle}>
          <img src={thumbnail} />
          <span class="flex-1">{props.title}</span>
          <span class="space-x-4px">
            {actions.map((action) =>
              action.getVisible.call(editor, comp) ? (
                <action.component
                  class="p-4px"
                  key={comp.id}
                  value={action.getValue?.(comp)}
                  onClick={(e: MouseEvent) => {
                    e.stopPropagation();
                    action.onClick.call(editor, comp);
                  }}
                />
              ) : null
            )}
          </span>
        </div>
      );
    };
  },
});

const treeStyle = css`
  .ant-tree-switcher {
    display: flex;
    justify-content: center;
    align-items: center;
  }
`;

const nodeStyle = css`
  display: flex;
  align-items: center;
  padding: 6px;
  @apply rounded;
  > img {
    width: 24px;
    height: 24px;
    margin-right: 6px;
    object-fit: contain;
  }
`;
