<template>
  <div v-if="!selectedCustomerType && isNewCustomer && !props.customerType" class="p-5">
    <h3 class="title is-4 mb-5 has-text-centered">
      {{ isVietnamese ? "Chọn loại khách hàng" : "Select Customer Type" }}
    </h3>
    <div class="columns is-multiline">
      <div class="column is-6">
        <button
          :disabled="!$getEditRights('edit', { code: 'individual', category: 'submenu' })"
          class="button is-large is-fullwidth" 
          style="height: 120px" 
          @click="selectCustomerType(1)"
        >
          <div class="has-text-centered">
            <div>
              <SvgIcon v-bind="{ name: 'user.svg', type: 'black', size: 40 }"></SvgIcon>
            </div>
            <div class="title is-5 mb-0">
              {{ isVietnamese ? "Cá nhân" : "Individual" }}
            </div>
          </div>
        </button>
      </div>
      <div class="column is-6">
        <button           
          :disabled="!$getEditRights('edit', { code: 'org', category: 'submenu' })"
          class="button is-large is-fullwidth" 
          style="height: 120px" 
          @click="selectCustomerType(2)"
        >
          <div class="has-text-centered">
            <div>
              <SvgIcon v-bind="{ name: 'building.svg', type: 'black', size: 40 }"></SvgIcon>
            </div>
            <div class="title is-5 mb-0">
              {{ isVietnamese ? "Tổ chức" : "Organization" }}
            </div>
          </div>
        </button>
      </div>
    </div>
  </div>

  <template v-else-if="isLoaded">
    <div v-if="record && isLoaded">
      <div class="columns is-multiline">
        <div class="column is-4">
          <div class="field">
            <label class="label">{{ isIndividual ? "Họ và tên" : "Tên tổ chức" }}<b class="ml-1 has-text-danger">*</b></label>
            <div class="control">
              <input class="input" type="text" v-model="record.fullname" />
            </div>
            <p class="help is-danger" v-if="errors.fullname">{{ errors.fullname }}</p>
          </div>
        </div>
        <div class="column is-4">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("phone_number")[lang] }}<b class="ml-1 has-text-danger">*</b></label>
            <InputPhone v-bind="{ record: record, attr: 'phone' }" @phone="selected('phone', $event)"></InputPhone>
            <p class="help is-danger" v-if="errors.phone">
              {{ errors.phone }}
              <a class="has-text-primary" v-if="existedCustomer" @click="showCustomer()">Chi tiết</a>
            </p>
          </div>
        </div>
        <div class="column is-4">
          <div class="field">
            <label class="label">Email</label>
            <InputEmail v-bind="{ record: record, attr: 'email' }" @email="selected('email', $event)"></InputEmail>
            <p class="help is-danger" v-if="errors.email">{{ errors.email }}</p>
          </div>
        </div>
      </div>
      <div class="columns is-multiline">
        <div class="column is-6">
          <div class="field">
            <label class="label">Địa chỉ liên hệ</label>
            <input class="input" type="text" v-model="record.contact_address" />
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">{{ isIndividual ? 'Địa chỉ thường trú' : 'Địa chỉ đăng ký' }}</label>
            <input class="input" type="text" v-model="record.address" />
          </div>
        </div>
      </div>

      <div v-if="isOrganization" class="columns is-multiline">
        <div class="column is-6">
          <div class="field">
            <label class="label">Tài khoản ngân hàng</label>
            <input class="input" type="text" v-model="organizationData.bank_account" />
          </div>
        </div>
        <div class="column is-6">
          <div class="field">
            <label class="label">Tên ngân hàng</label>
            <input class="input" type="text" v-model="organizationData.bank_name" />
          </div>
        </div>
      </div>

      <div class="columns is-multiline">
        <div class="column is-3">
          <div class="field">
            <label class="label">{{ isIndividual ? 'Giấy tờ tùy thân' : 'Giấy tờ' }}<b class="ml-1 has-text-danger">*</b></label>
            <SearchBox v-bind="{ vdata: filteredLegalTypes, api: 'legaltype', field: isVietnamese ? 'name' : 'en', column: ['name', 'en'], first: true, optionid: record.legal_type }" @option="selected('legal_type', $event)"></SearchBox>
          </div>
        </div>
        <div class="column is-3">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("idnum")[lang] }}<b class="ml-1 has-text-danger">*</b></label>
            <input class="input" type="text" v-model="record.legal_code" />
            <p class="help is-danger" v-if="errors.legal_code">{{ errors.legal_code }}</p>
          </div>
        </div>
        <div class="column is-3">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("issued_date")[lang] }}<b class="ml-1 has-text-danger">*</b></label>
            <Datepicker v-bind="{ record: record, attr: 'issued_date', maxdate: new Date() }" @date="selected('issued_date', $event)"></Datepicker>
            <p class="help is-danger" v-if="errors.issued_date">{{ errors.issued_date }}</p>
          </div>
        </div>
        <div class="column is-3">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("issued_place")[lang] }}</label>
            <SearchBox
                v-bind="{ api: 'issuedplace', field: 'name', column: ['name'], first: true, position: 'is-bottom-right', optionid: record.issued_place,filter: {id__in: isIndividual ? [2, 3] : [4, 5] } }"
                @option="selected('issued_place', $event)"></SearchBox>
          </div>
        </div>
      </div>

      <div class="columns is-multiline" v-if="isIndividual">
        <div class="column is-3">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("gender")[lang] }}</label>
            <SearchBox v-bind="{ vdata: store.sex, api: 'sex', field: isVietnamese ? 'name' : 'en', column: ['name', 'en'], first: true, optionid: individualData.sex }" @option="selectedIndividual('sex', $event)"></SearchBox>
          </div>
        </div> 
        <div class="column is-3">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("birth_date")[lang] }}</label>
            <Datepicker v-bind="{ record: individualData, attr: 'dob', maxdate: new Date() }" @date="selectedIndividual('dob', $event)"></Datepicker>
            <p class="help is-danger" v-if="errors.dob">{{ errors.dob }}</p>
          </div>
        </div>
      </div>

      <div class="columns is-multiline">
        <div class="column is-12">
          <div class="field">
            <label class="label">{{ dataLang && findFieldName("note")[lang] }}</label>
            <textarea class="textarea" v-model="record.note" rows="2"></textarea>
          </div>
        </div>
      </div>

      <div class="mt-5 mb-4">
        <h4 class="title is-6 has-text-warning">{{ isIndividual ? 'Người liên quan' : 'Người đại diện pháp luật' }}</h4>
      </div>
      <div class="columns is-multiline mb-0 is-2" v-for="(v, i) in localPeople" :key="i">
        <div class="column">
          <label class="label" v-if="i === 0">{{ findFieldName("select")[lang] }}</label>
          <SearchBox 
            v-bind="{ 
              api: 'people',
              field: 'label',
              column: ['code', 'fullname', 'phone'],
              first: true,
              optionid: v.people,
              position: 'is-top-left',
              addon: peopleAddon,
              viewaddon: peopleviewAddon
            }" 
            @option="selectPeople($event, v, i)"></SearchBox>
        </div>
        <div class="column is-4">
          <label class="label" v-if="i === 0">{{ isIndividual ? 'Quan hệ' : 'Chức vụ' }}</label>
          <SearchBox 
            v-bind="{ 
              api: 'relation',
              field: store.lang === 'en' ? 'en' : 'name',
              column: ['code', 'name', 'en'], 
              first: true, 
              optionid: v.relation, 
              position: 'is-top-left',
              filter:{ id__in: isIndividual ? [1,2,3,4,5,6,7,8] : [9,10,11,12] } 
            }" 
            @option="selectRelation($event, v, i)"
          />
        </div>
        <div class="column is-narrow">
          <label class="label" v-if="i === 0">&nbsp;</label>
          <div class="buttons is-gap-0.5 is-flex-wrap-nowrap are-small" style="height: 40px">
            <button class="button is-dark" @click="add()">
              <span class="icon">
                <SvgIcon v-bind="{ name: 'add4.svg', type: 'white', size: 20 }"></SvgIcon>
              </span>
            </button>
            <button class="button is-dark" @click="remove(v, i)">
              <span class="icon">
                <SvgIcon v-bind="{ name: 'bin1.svg', type: 'white', size: 20 }"></SvgIcon>
              </span>
            </button>
          </div>
        </div>
      </div>

      <div class="mt-5 buttons is-right">
        <button class="button" @click="emit('close')">{{ isVietnamese ? 'Hủy' : 'Cancel' }}</button>
        <button class="button is-primary" @click="update()">{{ isVietnamese ? 'Lưu lại' : 'Save' }}</button>
      </div>

      <Modal @close="showmodal = undefined" v-bind="showmodal" v-if="showmodal"></Modal>
    </div>
  </template>
</template>

<script setup>
import { ref, computed, onMounted, watch } from "vue";
import { useNuxtApp } from "#app";
import InputPhone from "~/components/common/InputPhone";
import InputEmail from "~/components/common/InputEmail";
import SearchBox from "~/components/SearchBox";
import Datepicker from "~/components/datepicker/Datepicker";
import { useStore } from "~/stores/index";
import { isEqual, pick } from 'es-toolkit';

const emit = defineEmits(["close", "update", "modalevent"]);
const { $getdata, $patchapi, $insertapi, $deleteapi, $empty, $errPhone, $resetNull, $snackbar, $copy } = useNuxtApp();

const props = defineProps({
  pagename: String,
  row: Object,
  application: Object,
  customerType: Number,
});

const store = useStore();
const lang = computed(() => store.lang);
const isVietnamese = computed(() => lang.value === "vi");
const dataLang = ref(store.common);

const errors = ref({});
const record = ref({});
const individualData = ref({});
const organizationData = ref({});
const isLoaded = ref(false);
const isNewCustomer = ref(true);
const selectedCustomerType = ref(null);
const showmodal = ref();
const existedCustomer = ref(undefined);
const people = ref([]);
const localPeople = ref([]); // { id?: number; people: number; relation: number }[]

const isIndividual = computed(() => selectedCustomerType.value === 1);
const isOrganization = computed(() => selectedCustomerType.value === 2);

const filteredLegalTypes = computed(() => {
  if (!store.legaltype) return [];
  return isOrganization.value ? store.legaltype.filter(lt => lt.id === 4) : store.legaltype.filter(lt => lt.id !== 4);
});

const peopleAddon = { 
  component: "people/People",
  width: "65%",
  height: "500px", 
  title: store.lang === "en" ? "Related person" : "Người liên quan" 
};
const peopleviewAddon = { ...peopleAddon };

function selectCustomerType(type) {
  const typeNum = Number(type);
  selectedCustomerType.value = typeNum;
  record.value = { fullname: "", phone: "", email: "", country: 1, type: typeNum, legal_type: typeNum === 2 ? 4 : null, creator: store.login.id, updater: store.login.id };
  if (typeNum === 1) {
    individualData.value = { dob: null, sex: 1 };
    organizationData.value = {};
  } else {
    individualData.value = {};
    organizationData.value = { established_date: null };
  }
  people.value = [{}];
  isLoaded.value = true;
}

function findFieldName(code) {
  return dataLang.value.find(item => item.code === code) || { vi: code, en: code };
}

function showCustomer() {
  showmodal.value = { component: "customer/CustomerView", width: "60%", height: "600px", title: "Khách hàng", vbind: { row: existedCustomer.value } };
}

const selected = (f, v) => { record.value[f] = (v && typeof v === 'object') ? v.id : v; if (errors.value[f]) delete errors.value[f]; };
const selectedIndividual = (f, v) => { individualData.value[f] = (v && typeof v === 'object') ? v.id : v; };
const selectedOrg = (f, v) => { organizationData.value[f] = (v && typeof v === 'object') ? v.id : v; };
const selectPeople = (opt, _v, i) => { 
  localPeople.value[i].people = opt.id; 
};
const selectRelation = (opt, _v, i) => { localPeople.value[i].relation = opt ? opt.id : null; };
const add = () => localPeople.value.push({});
const remove = (_v, i) => {
  localPeople.value.splice(i, 1);
  if (localPeople.value.length === 0) localPeople.value = [{}];
};

watch(people, (val) => {
  localPeople.value = val.map(cp => pick(cp, ['id', 'people', 'relation']));
}, { deep: true })

function checkError() {
  errors.value = {};
  if ($empty(record.value.fullname)) errors.value.fullname = isVietnamese.value ? "Họ tên không được bỏ trống" : "Full name is required";
  if ($empty(record.value.phone)) {
    errors.value.phone = isVietnamese.value ? "Số điện thoại không được bỏ trống" : "Phone is required";
  } else {
    const text = $errPhone(record.value.phone);
    if (text) errors.value.phone = text;
  }
  if ($empty(record.value.legal_code)) errors.value.legal_code = isVietnamese.value ? "Mã số không được bỏ trống" : "Legal code is required";
  if ($empty(record.value.issued_date)) errors.value.issued_date = "Ngày cấp không được bỏ trống";

  return Object.keys(errors.value).length > 0;
}

async function update() {
  try {
    if (checkError()) return;

    if (isNewCustomer.value) {
      if (record.value.phone) {
        const phoneCheck = await $getdata("customer", { phone: record.value.phone.trim() }, undefined, true);
        if (phoneCheck) {
          existedCustomer.value = phoneCheck;
          errors.value.phone = isVietnamese.value ? "Số điện thoại đã tồn tại." : "Phone already exists.";
          return;
        }
      }
      if (record.value.email) {
        const emailCheck = await $getdata("customer", { email: record.value.email.trim() }, undefined, true);
        if (emailCheck) {
          existedCustomer.value = emailCheck;
          errors.value.email = isVietnamese.value ? "Email đã tồn tại." : "Email already exists.";
          return;
        }
      }
      if (record.value.legal_code) {
        const legalCheck = await $getdata("customer", { legal_code: record.value.legal_code }, undefined, true);
        if (legalCheck) { errors.value.legal_code = "Số CMND/CCCD đã tồn tại."; return; }
      }
    }

    let customerData = $resetNull({ ...record.value });
    customerData.type = selectedCustomerType.value;
    customerData.updater = store.login.id;
    customerData.update_time = new Date();

    let res = isNewCustomer.value ? await $insertapi("customer", customerData, undefined, false) : await $patchapi("customer", customerData, undefined, false);
    if (!res || res === "error") return;

    const customerId = res.id;
    let organizationId = organizationData.value?.id;

    if (isIndividual.value) {
      let indPayload = $resetNull({ ...individualData.value });
      indPayload.customer = customerId;
      if (individualData.value.id) await $patchapi("individual", { ...indPayload, id: individualData.value.id }, undefined, false);
      else await $insertapi("individual", indPayload, undefined, false);
    } else if (isOrganization.value) {
      let orgPayload = $resetNull({ ...organizationData.value });
      orgPayload.customer = customerId;
      let orgRes;
      if (organizationData.value.id) {
        orgRes = await $patchapi("organization", { ...orgPayload, id: organizationData.value.id }, undefined, false);
      } else {
        orgRes = await $insertapi("organization", orgPayload, undefined, false);
      }
      if (orgRes && orgRes.id) {
        organizationId = orgRes.id;
      }
    }

    // Người liên quan / Người đại diện
    const apiName = isIndividual.value ? "customerpeople" : "legalrep";
    let commonPayload = {};
    if (isIndividual.value) {
      commonPayload = { customer: customerId };
    }
    if (isOrganization.value && organizationId) {
      commonPayload = { organization: organizationId };
    }

    const validLocalPeople = localPeople.value.filter(lp => lp.people && lp.relation).map(lp => toRaw(lp));
    const peopleKeys = people.value.map(p => pick(p, ['id', 'people', 'relation']));

    // 1. check existing ids, if people or relation changes -> patch
    const existingLocalPeople = validLocalPeople.filter(cp => Boolean(cp.id));
    existingLocalPeople.forEach(lp => {
      const match = peopleKeys.find(p => isEqual(p, lp));
      const payload = { ...lp, ...commonPayload }
      
      if (!match) {
        $patchapi(apiName, payload);
      }
    });
   
    // 2. if localPeople has and people doesn't -> insert
    validLocalPeople.forEach(lp => {
      if (!lp.id) {
        const payload = { ...lp, ...commonPayload };
        $insertapi(apiName, payload);
      }
    });

    // 3. if people has and localPeople doesn't -> delete
    if (peopleKeys.length !== 0 && validLocalPeople.length !== 0) {
      peopleKeys.forEach(cp => {
        const match = validLocalPeople.find(lp => cp.id === lp.id);
        if (!match) {
          $deleteapi(apiName, cp.id);
        }
      });
    }

    // Ảnh
    if (record.value.image && record.value.image.length > 0) {
      await $insertapi("customerfile", record.value.image.map(v => ({ ref: customerId, file: v })), undefined, false);
    }

    const completeData = await $getdata("customer", { id: customerId }, undefined, true);
    
    $snackbar(`Khách hàng đã được ${isNewCustomer.value ? "khởi tạo" : "cập nhật"} thành công`, "Thành công");

    emit("modalevent", { name: "dataevent", data: completeData });
    emit("update", completeData);
    setTimeout(() => emit("close"), 100);
  } catch (e) { console.error(e); }
}

async function initData() {
  if (props.row && props.row.id) {
    isNewCustomer.value = false;
    selectedCustomerType.value = Number(props.row.type);
    record.value = { ...props.row };
    if (isIndividual.value) {
      const ind = await $getdata("individual", { customer: props.row.id }, undefined, true);
      individualData.value = ind || { dob: null, sex: 1 };
      const rows = await $getdata("customerpeople", { customer: props.row.id });
      people.value = rows.length > 0 ? rows : [{}];
    } else {
      const org = await $getdata("organization", { customer: props.row.id }, undefined, true);
      organizationData.value = org || { established_date: null };
      if (org && org.id) {
        const rows = await $getdata("legalrep", { organization: org.id });
        people.value = rows.length > 0 ? rows : [{}];
      } else {
        people.value = [{}];
      }
    }
    isLoaded.value = true;
  } else if (props.application && props.application.id) {
    const copyData = $copy(props.application);
    const type = props.customerType || copyData.type || 1;
    selectCustomerType(type);
    record.value = { ...record.value, ...copyData, id: undefined, code: undefined };
    individualData.value = { ...individualData.value, ...copyData };
  } else if (props.customerType) {
    selectCustomerType(props.customerType);
  }
}

onMounted(() => initData());
</script>