import NodeTableComponent, {
  DataTemplateInterface,
} from "../NodeTableComponent/NodeTableComponent";
import { useEffect, useMemo, useState } from "react";
import { invoke } from "@tauri-apps/api/core";
import styles from "./SectionHeaders.module.scss";
import {
  Flex,
  Button,
  Modal,
  Form,
  Input,
  InputNumber,
  Select,
  message,
  // message,
} from "antd";
import { PlusOutlined, EditOutlined } from "@ant-design/icons";

const dataTemplate: DataTemplateInterface = {
  name: {
    name: "name",
    offset: 0,
    size: 8,
    data_type: "char_array",
    description: "节区的名称，一般以.开头",
  },
  virtual_size: {
    name: "virtual_size",
    offset: 8,
    size: 4,
    data_type: "hex",
    description: "在内存中的大小,不能为0",
  },
  virtual_address: {
    name: "virtual_address",
    offset: 12,
    size: 4,
    data_type: "hex",
    description: "在内存中的地址(VA)",
  },
  size_of_raw_data: {
    name: "size_of_raw_data",
    offset: 16,
    size: 4,
    data_type: "hex",
    description: "在文件中的大小",
  },
  pointer_to_raw_data: {
    name: "pointer_to_raw_data",
    offset: 20,
    size: 4,
    data_type: "hex",
    description: "在文件中的偏移",
  },
  pointer_to_relocations: {
    name: "pointer_to_relocations",
    offset: 24,
    size: 4,
    data_type: "hex",
    description: "重定位表的偏移",
  },
  pointer_to_linenumbers: {
    name: "pointer_to_linenumbers",
    offset: 28,
    size: 4,
    data_type: "hex",
    description: "行号表的偏移",
  },
  number_of_relocations: {
    name: "number_of_relocations",
    offset: 32,
    size: 2,
    data_type: "hex",
    description: "重定位表的数量",
  },
  number_of_linenumbers: {
    name: "number_of_linenumbers",
    offset: 34,
    size: 2,
    data_type: "hex",
    description: "行号表的数量",
  },
  characteristics: {
    name: "characteristics",
    offset: 36,
    size: 4,
    data_type: "hex",
    description: "属性",
  },
};
// 节区属性
const sectionCharacteristics = [
  {
    value: 0x80000000,
    label: "可写",
  },
  {
    value: 0x40000000,
    label: "可读",
  },
  {
    value: 0x20000000,
    label: "可执行",
  },
  {
    value: 0x02000000,
    label: "可丢弃",
  },
  {
    value: 0x04000000,
    label: "不可缓存",
  },
  {
    value: 0x08000000,
    label: "不可分页",
  },
  {
    value: 0x10000000,
    label: "可共享",
  },
  {
    value: 0x01000000,
    label: "包含扩展重定位",
  },
  {
    value: 0x00000020,
    label: "包含可执行代码",
  },
  {
    value: 0x00000040,
    label: "包含已初始化数据",
  },
  {
    value: 0x00000080,
    label: "包含未初始化数据",
  },
  {
    value: 0x00000200,
    label: "包含注释或信息",
  },
  {
    value: 0x00000800,
    label: "将不会成为镜像的一部分",
  },
  {
    value: 0x00001000,
    label: "包含 COMDAT 数据",
  },
  {
    value: 0x00100000,
    label: "数据对齐到 1 字节边界",
  },
  {
    value: 0x00200000,
    label: "数据对齐到 2 字节边界",
  },
  {
    value: 0x00300000,
    label: "数据对齐到 4 字节边界",
  },
  {
    value: 0x00400000,
    label: "数据对齐到 8 字节边界",
  },
  {
    value: 0x00500000,
    label: "数据对齐到 16 字节边界",
  },
  {
    value: 0x00600000,
    label: "数据对齐到 32 字节边界",
  },
  {
    value: 0x00700000,
    label: "数据对齐到 64 字节边界",
  },
  {
    value: 0x00800000,
    label: "数据对齐到 128 字节边界",
  },
  {
    value: 0x00900000,
    label: "数据对齐到 256 字节边界",
  },
  {
    value: 0x00a00000,
    label: "数据对齐到 512 字节边界",
  },
  {
    value: 0x00b00000,
    label: "数据对齐到 1024 字节边界",
  },
  {
    value: 0x00c00000,
    label: "数据对齐到 2048 字节边界",
  },
  {
    value: 0x00d00000,
    label: "数据对齐到 4096 字节边界",
  },
  {
    value: 0x00e00000,
    label: "数据对齐到 8192 字节边界",
  },
  {
    value: 0x00f00000,
    label: "数据对齐掩码",
  },
  {
    value: 0x00000001,
    label: "预留：DSECT 类型",
  },
  {
    value: 0x00000002,
    label: "预留：不加载",
  },
  {
    value: 0x00000004,
    label: "预留：组节区",
  },
  {
    value: 0x00000008,
    label: "预留：不填充节区",
  },
  {
    value: 0x00000010,
    label: "预留：COPY 类型",
  },
  {
    value: 0x00000100,
    label: "预留：其他链接信息",
  },
  {
    value: 0x00000400,
    label: "预留：覆盖节区",
  },
];

// 节区头大小
const sectionHeaderSize = 40;

export default function SectionHeaders() {
  const [data, setData] = useState([]);
  const [addSectionVisible, setAddSectionVisible] = useState(false);
  const [addSectionLoading, setAddSectionLoading] = useState(false);
  const [addSectionForm] = Form.useForm();

  const command = "command_get_pe_data_section_headers";

  const columns = [
    {
      title: "字段名",
      dataIndex: "name",
      key: "name",
    },
    {
      title: "偏移",
      dataIndex: "offset",
      key: "offset",
      hexSwitch: true,
    },
    {
      title: "大小",
      dataIndex: "size",
      key: "size",
    },
    {
      title: "值",
      dataIndex: "value",
      key: "value",
      hexSwitch: true,
      editable: true,
    },
    {
      title: "描述信息",
      dataIndex: "description",
      key: "description",
    },
  ];

  const formatDataHandler = (data: any) => {
    const { base_offset } = data;
    return (
      data?.fields?.map((item: any, index: number) => {
        return {
          base_offset: base_offset + index * sectionHeaderSize,
          fields: { ...item },
        };
      }) || []
    );
  };

  const requestAddSection = async (
    sectionName: string,
    sectionSize: number,
    sectionCharacteristics: number
  ) =>
    invoke("command_add_section", {
      sectionName,
      sectionSize,
      sectionCharacteristics,
    });

  const AddSectionModel = useMemo(() => {
    const handelOk = () => {
      const { name, size, characteristics } = addSectionForm.getFieldsValue();
      console.log(
        "send",
        name,
        size,
        characteristics.reduce((a, b) => a + b)
      );
      setAddSectionLoading(true);
      requestAddSection(
        name,
        size,
        characteristics.reduce((a, b) => a + b)
      )
        .then((_res) => {
          requestData();
          setAddSectionLoading(false);
          setAddSectionVisible(false);
          message.success("添加节成功");
        })
        .catch((_err) => {
          setAddSectionLoading(false);
          message.error(`添加节失败:${_err}`);
        });
    };

    return (
      <Modal
        title="添加节"
        open={addSectionVisible}
        onOk={handelOk}
        loading={addSectionLoading}
        onCancel={() => setAddSectionVisible(false)}
      >
        <Form
          form={addSectionForm}
          name="control-hooks"
          onFinish={(values) => {
            console.log(values);
          }}
          style={{ maxWidth: 600 }}
        >
          <Form.Item
            name="name"
            label="节区名"
            rules={[{ required: true, type: "string", max: 8 }]}
          >
            <Input />
          </Form.Item>
          <Form.Item
            name="size"
            label="大小"
            initialValue={0}
            rules={[{ required: true, type: "number" }]}
          >
            <InputNumber min={0} />
          </Form.Item>
          <Form.Item
            name="characteristics"
            label="属性"
            // 0xC0000020
            initialValue={[0x40000000, 0x20000000, 0x00000020]}
            rules={[{ required: false }]}
          >
            <Select
              mode="multiple"
              style={{ width: "100%" }}
              placeholder="Please select"
            >
              {sectionCharacteristics.map((item) => {
                return (
                  <Select.Option value={item.value}>
                    {item.label}-0x{item.value.toString(16).toUpperCase()}
                  </Select.Option>
                );
              })}
            </Select>
          </Form.Item>
        </Form>
      </Modal>
    );
  }, [addSectionVisible, addSectionLoading]);

  const requestData = () => {
    invoke(command).then((res) => {
      setData(formatDataHandler(res));
    });
  };

  const handleRequestExtendLastSection = () => {
    message.warning("暂未实现");
  };

  useEffect(() => {
    requestData();
  }, []);
  return (
    <Flex className={styles.content}>
      {AddSectionModel}
      <Flex className={styles.optionContainer}>
        <Button
          type="primary"
          icon={<PlusOutlined />}
          onClick={() => setAddSectionVisible(true)}
          className={styles.optionItem}
        >
          添加节
        </Button>
        <Button
          type="primary"
          icon={<EditOutlined />}
          className={styles.optionItem}
          onClick={handleRequestExtendLastSection}
        >
          扩展最后一节大小
        </Button>
      </Flex>

      {data.map((item, index) => {
        return (
          <div className={styles.tableItem}>
            <NodeTableComponent
              key={index}
              dataTemplate={dataTemplate}
              defaultData={item}
              columns={columns as any}
            />
          </div>
        );
      })}
    </Flex>
  );
}
