<template>
  <div class="tabs is-boxed">
    <ul>
      <li
        :class="selectType.code === v.code ? 'is-active fs-16' : 'fs-16'"
        v-for="v in fieldType"
      >
        <a @click="selectType = v"
          ><span>{{ v.name }}</span></a
        >
      </li>
    </ul>
  </div>
  <template v-if="selectType.code === 'formula'">
    <b-radio
      :class="i === 1 ? 'ml-5' : null"
      v-model="choice"
      v-for="(v, i) in choices"
      :key="i"
      :native-value="v.code"
    >
      <span :class="v.code === choice ? 'fsb-16' : 'fs-16'">{{ v.name }}</span>
    </b-radio>
    <div class="has-background-light mt-3 px-3 py-3">
      <div
        class="tags are-medium mb-0"
        v-if="choice === 'function'"
      >
        <span
          :class="`tag ${func === v.code ? 'is-primary' : 'is-dark'} is-rounded is-clickable`"
          v-for="(v, i) in funcs"
          :key="i"
          @click="changeFunc(v)"
          @dblclick="addFunc(v)"
          >{{ v.name }}</span
        >
      </div>
      <template v-else>
        <div class="field px-0 mx-0">
          <label class="label fs-14">Chọn trường<span class="has-text-danger"> *</span> </label>
          <div class="control">
            <!--<b-taginput
        size="is-small"
          v-model="tags"
          :data="fields.filter(v=>v.format==='number')"
          type="is-dark is-light"
          autocomplete
          :open-on-focus="true"
          field="caption"
          icon="plus"
          placeholder="Chọn trường"
         >
          <template slot-scope="props">
            <span class="mr-3 has-text-danger">{{props.option.name}}</span> 
            <span :class="tags.find(v=>v.id===props.option.id)? 'has-text-dark' : ''">{{$stripHtml(props.option.label,50)}}</span>
          </template>
          <template slot="empty">
            Không có trường thỏa mãn
          </template>
        </b-taginput>-->
          </div>
          <p
            class="help has-text-danger"
            v-if="errors.find((v) => v.name === 'tags')"
          >
            {{ errors.find((v) => v.name === "tags").message }}
          </p>
        </div>
        <div
          class="field mt-3"
          v-if="tags.length > 0"
        >
          <p class="help is-primary mb-1">Click đúp vào để thêm vào công thức tính.</p>
          <div class="tags mb-2">
            <span
              @dblclick="formula = formula ? formula + ' ' + v.name : v.name"
              class="tag is-dark is-rounded is-clickable"
              v-for="v in tags"
            >
              {{ v.name }}
            </span>
          </div>
          <div class="tags">
            <span
              v-for="(v, i) in operator"
              :key="i"
            >
              <span
                @dblclick="addOperator(v)"
                class="tag is-primary is-rounded is-clickable mr-4"
              >
                <span class="fs-16">{{ v.code }}</span>
              </span>
            </span>
          </div>
        </div>
      </template>
      <div class="field mt-3 px-0 mx-0">
        <label class="label fs-14">Công thức tính <span class="has-text-danger"> * </span> </label>
        <p class="control">
          <textarea
            class="textarea"
            rows="3"
            type="text"
            :placeholder="placeholder"
            v-model="formula"
          >
          </textarea>
        </p>
        <p
          class="help has-text-danger"
          v-if="errors.find((v) => v.name === 'formula')"
        >
          {{ errors.find((v) => v.name === "formula").message }}
        </p>
      </div>
    </div>
    <div class="field is-horizontal mt-3 px-0 mx-0">
      <div class="field-body">
        <div class="field">
          <label class="label fs-14">Hiển thị theo <span class="has-text-danger"> * </span> </label>
          <div class="control">
            <b-autocomplete
              size="is-small"
              icon-right="magnify"
              :value="selectUnit ? selectUnit.name : ''"
              placeholder=""
              :keep-first="true"
              :open-on-focus="true"
              :data="moneyunit"
              field="name"
              @select="(option) => (selectUnit = option)"
            >
            </b-autocomplete>
          </div>
        </div>
        <div class="field">
          <label class="label fs-14">Phần thập phân</label>
          <div class="control">
            <input
              class="input is-small"
              type="text"
              placeholder=""
              v-model="decimal"
            />
          </div>
        </div>
      </div>
    </div>
  </template>
  <div class="field px-0 mx-0">
    <label class="label">Tên trường <span class="has-text-danger"> * </span> </label>
    <p class="control">
      <input
        class="input"
        type="text"
        placeholder="Tên trường phải là duy nhất"
        v-model="name"
        :readonly="selectType ? selectType.code === 'formula' : false"
      />
    </p>
    <p
      class="help has-text-danger"
      v-if="errors.find((v) => v.name === 'name')"
    >
      {{ errors.find((v) => v.name === "name").message }}
    </p>
    <p
      class="help has-text-primary"
      v-else
    >
      Tên trường do hệ thống tự sinh.
    </p>
  </div>
  <div class="mt-5">
    <label class="label">Mô tả<span class="has-text-danger"> *</span></label>
    <div class="field has-addons">
      <div class="control is-expanded">
        <input
          class="input"
          type="text"
          v-model="label"
        />
      </div>
      <div class="control">
        <button
          class="button"
          @click="editLabel()"
        >
          <span><SvgIcon v-bind="{ name: 'pen.svg', type: 'dark', size: 17 }"></SvgIcon></span>
        </button>
      </div>
    </div>
    <p
      class="help has-text-danger"
      v-if="errors.find((v) => v.name === 'label')"
    >
      {{ errors.find((v) => v.name === "label").message }}
    </p>
  </div>
  <div
    class="field mt-5"
    v-if="selectType.code === 'empty'"
  >
    <label class="label"
      >Kiểu dữ liệu
      <span class="has-text-danger"> * </span>
    </label>
    <div class="control fs-14">
      <span
        class="mr-4"
        v-for="(v, i) in datatype"
      >
        <a
          class="icon-text"
          @click="changeType(v)"
        >
          <SvgIcon
            v-bind="{
              name: `radio-${radioType.code === v.code ? '' : 'un'}checked.svg`,
              type: 'gray',
              size: 22,
            }"
          ></SvgIcon>
        </a>
        {{ v.name }}
      </span>
    </div>
  </div>
  <div class="field mt-5">
    <p class="control">
      <a
        class="button is-primary has-text-white"
        @click="selectType.code === 'formula' ? createField() : createEmptyField()"
        >Tạo cột</a
      >
    </p>
  </div>
  <Modal
    v-bind="showmodal"
    v-if="showmodal"
    @label="changeLabel"
    @close="close"
  ></Modal>
</template>
<script setup>
import { useStore } from "@/stores/index";
import ScrollBox from "~/components/datatable/ScrollBox";
const emit = defineEmits(["modalevent"]);
const store = useStore();
const { $id, $copy, $clone, $empty, $stripHtml, $createField, $calc, $isNumber } = useNuxtApp();
var props = defineProps({
  pagename: String,
  field: Object,
  filters: Object,
  filterData: Object,
  width: String,
});
const moneyunit = store.moneyunit;
const datatype = store.datatype;
var showmodal = ref();
var pagedata = store[props.pagename];
var selectUnit = moneyunit.find((v) => v.code === "one");
var data = [];
var current = 1;
var filterData = [];
var loading = false;
var fieldType = [
  { code: "formula", name: "Tạo công thức" },
  { code: "empty", name: "Tạo cột rỗng" },
];
var errors = [];
var tags = [];
var formula = undefined;
var name = `f${$id().toLocaleLowerCase()}`;
var label = undefined;
var errors = [];
var selectType = fieldType.find((v) => v.code === "empty");
var radioType = ref(datatype.find((v) => v.code === "string"));
var fields = [];
var options = undefined;
var columns = $copy(pagedata.fields.filter((v) => v.format === "number"));
var decimal = undefined;
var choices = [
  { code: "column", name: "Dùng cột dữ liệu" },
  { code: "function", name: "Dùng hàm số" },
];
var choice = "column";
var funcs = [
  { code: "sum", name: "Sum" },
  { code: "max", name: "Max" },
  { code: "min", name: "Min" },
  { code: "avg", name: "Avg" },
];
var func = "sum";
var placeholder = "Minh hoạ công thức: f10001 + f10002";
var args = undefined;
var operator = [
  { code: "+", name: "Cộng" },
  { code: "-", name: "Trừ" },
  { code: "*", name: "Nhân" },
  { code: "/", name: "Chia" },
  { code: ">", name: "Lớn hơn" },
  { code: ">=", name: "Lớn hơn hoặc bằng" },
  { code: "<", name: "Nhỏ hơn" },
  { code: "<=", name: "Nhỏ hơn hoặc bằng" },
  { code: "==", name: "Bằng" },
  { code: "&&", name: "Và" },
  { code: "||", name: "Hoặc" },
  { code: "iif", name: "Điều kiện rẽ nhánh" },
];
function editLabel() {
  if ($empty(label)) return;
  showmodal.value = {
    component: "datatable/EditLabel",
    width: "500px",
    height: "300px",
    vbind: { label: label },
  };
}
function close() {
  showmodal.value = null;
}
function changeLabel(evt) {
  label = evt;
  showmodal.value = null;
}
function changeType(v) {
  radioType.value = v;
}
function addFunc(v) {
  formula = (formula ? formula + " " : "") + v.name + "(C0: C2)";
}
function addOperator(v) {
  let text = v.code === "iif" ? "a>b? c : d" : v.code;
  formula = `${formula || ""} ${text}`;
}
function changeFunc(v) {
  placeholder = `${v.name}(C0:C2) hoặc ${v.name}(C0,C1,C2). C là viết tắt của cột dữ liệu, số thứ tự của cột bắt đầu từ 0`;
  func = v.code;
}
function getFields() {
  fields = pagedata ? $copy(pagedata.fields) : [];
  fields.map((v) => (v.caption = (v.label ? v.label.indexOf("<") >= 0 : false) ? v.name : v.label));
}
function checkFunc() {
  let error = false;
  let val = formula.trim().replaceAll(" ", "");
  if (val.toLowerCase().indexOf(func) < 0) error = true;
  let start = val.toLowerCase().indexOf("(");
  let end = val.toLowerCase().indexOf(")");
  if (start < 0 || end < 0) error = true;
  let content = val.substring(start + 1, end);
  if ($empty(content)) error = true;
  let content1 = content.replaceAll(":", ",");
  let arr = content1.split(",");
  arr.map((v) => {
    let arr1 = v.toLowerCase().split("c");
    if (arr1.length !== 2) error = true;
    else if (!$isNumber(arr1[1])) error = true;
  });
  return error ? "error" : content;
}
function checkValid() {
  errors = [];
  if (tags.length === 0 && choice === "column") {
    errors.push({
      name: "tags",
      message: "Chưa chọn trường xây dựng công thức.",
    });
  }
  if (!$empty(formula) ? $empty(formula.trim()) : true) {
    errors.push({ name: "formula", message: "Công thức không được bỏ trống." });
  }
  if (!$empty(label) ? $empty(label.trim()) : true)
    errors.push({ name: "label", message: "Mô tả không được bỏ trống." });
  else if (pagedata.fields.find((v) => v.label.toLowerCase() === label.toLowerCase())) {
    errors.push({
      name: "label",
      message: "Mô tả bị trùng. Hãy đặt mô tả khác.",
    });
  }
  if (errors.length > 0) return false;
  //check formula in case use column
  if (choice === "column") {
    let val = $copy(formula);
    tags.forEach((v) => {
      let myRegExp = new RegExp(v.name, "g");
      val = val.replace(myRegExp, Math.random());
    });
    try {
      let value = $calc(val);
      if (isNaN(value) || value === Number.POSITIVE_INFINITY || value === Number.NEGATIVE_INFINITY) {
        errors.push({ name: "formula", message: "Công thức không hợp lệ" });
      }
    } catch (err) {
      console.log(err);
      errors.push({ name: "formula", message: "Công thức không hợp lệ" });
    }
  } else {
    if (checkFunc() === "error")
      errors.push({
        name: "formula",
        message: `Hàm ${func.toUpperCase()} không hợp lệ`,
      });
  }
  return errors.length > 0 ? false : true;
}
function createField() {
  if (!checkValid()) return;
  let field = $createField(name.trim(), label.trim(), "number", true);
  field.formula = formula.trim().replaceAll(" ", "");
  if (choice === "function") {
    field.func = func;
    field.vals = checkFunc();
  } else field.tags = tags.map((v) => v.name);
  field.level = Math.max(...pagedata.fields.map((v) => (v.level ? v.level : 0))) + 1;
  field.unit = selectUnit.detail;
  field.decimal = decimal;
  field.disable = "search,value";
  let copy = $copy(pagedata);
  copy.fields.push(field);
  store.commit(props.pagename, copy);
  emit("newfield", field);
  tags = [];
  formula = undefined;
  label = undefined;
  name = `f${$id()}`;
  emit("close");
}
function createEmptyField() {
  errors = [];
  if (!$empty(name) ? $empty(name.trim()) : true) errors.push({ name: "name", message: "Tên không được bỏ trống." });
  else if (pagedata.fields.find((v) => v.name.toLowerCase() === name.toLowerCase())) {
    errors.push({
      name: "name",
      message: "Tên trường bị trùng. Hãy đặt tên khác.",
    });
  }
  if (!$empty(label) ? $empty(label.trim()) : true)
    errors.push({ name: "label", message: "Mô tả không được bỏ trống." });
  else if (pagedata.fields.find((v) => v.label.toLowerCase() === label.toLowerCase())) {
    errors.push({
      name: "label",
      message: "Mô tả bị trùng. Hãy đặt mô tả khác.",
    });
  }
  if (errors.length > 0) return;
  let field = $createField(name.trim(), label.trim(), radioType.value.code, true);
  if (selectType.code === "chart") field = createChartField();
  let copy = $clone(pagedata);
  copy.fields.push(field);
  copy.update = { fields: copy.fields };
  store.commit(props.pagename, copy);
  //pagedata = copy
  emit("newfield", field);
  label = undefined;
  name = `f${$id()}`;
  emit("close");
}
function createChartField() {
  let array = pagedata.fields.filter((v) => v.format === "number" && v.show);
  if (args) array = $copy(args);
  let text = "";
  array.map((v, i) => (text += `'${v.name}${i < array.length - 1 ? "'," : "'"}`));
  let label = "";
  array.map((v, i) => (label += `'${$stripHtml(v.label)}${i < array.length - 1 ? "'," : "'"}`));
  let field = $createField(name.trim(), label.trim(), radioType.value.code, true);
  field.chart = "yes";
  field.template = `<TrendingChart class="is-clickable" v-bind="{row: row, fields: [${text}], labels: [${label}], width: '80', height: '26', 'header': ['stock_code', 'name']}"/>`;
  return field;
}
//============
getFields();
</script>
