<template>
  <CommonTopBanner :title="subTitle">
    <FlexCol padding="space.md">
      <LoadingPage v-if="loading" /> 
      <FlexCol>
        <Alert
          v-if="localSavedState"
          type="info"
          message="您的修改已经暂存，可以放心离开，下次接着编辑"
        />
        <Height :height="20" />
        <BackgroundBox
          backgroundImage="https://xy.wenlvti.net/app_static/images/village/BoxMid.png"
          :backgroundCutBorder="32"
          :backgroundCutBorderSize="36"
          :padding="24"
        >
          <ProvideVar :vars="{
            FieldBackgroundColor: 'transparent',
          }">
            <DynamicForm
              ref="formRef"
              :options="formDefine"
              :model="formModel"
              :globalParams="querys"
            />
          </ProvideVar>
        </BackgroundBox>
        <Height :height="20" />
        <Button v-if="querys.isView" type="primary" :loading="loading" @click="backPrev(false)">返回</Button>
        <FlexCol v-else :gap="10" center>
          <Height :height="20" />
          <PrimaryButton 
            text="提交"
            width="560rpx"
            @click="debounceSubmit.executeWithDelay()"
          />
          <Button v-if="querys.id" type="text" textColor="danger" :loading="loading" @click="deleteInfo">删除</Button>
        </FlexCol>
      </FlexCol>
      <XBarSpace />
    </FlexCol>
  </CommonTopBanner>
</template>

<script setup lang="ts">
import { nextTick, ref, watch, type Ref } from 'vue';
import { useLoadQuerys } from '@/components/composeabe/LoadQuerys';
import { CollectableModulesIdMap, getVillageInfoForm, getVillageInfoFormIds, type SingleForm } from './forms';
import { showError } from '@/common/composeabe/ErrorDisplay';
import { backAndCallOnPageBack } from '@/components/utils/PageAction';
import { toast } from '@/components/utils/DialogAction';
import { alert, confirm } from '@/components/dialog/CommonRoot';
import { Debounce, RequestApiError, waitTimeOut } from '@imengyu/imengyu-utils';
import VillageInfoApi, { CommonInfoModel } from '@/api/inhert/VillageInfoApi';
import DynamicForm from '@/components/dynamic/DynamicForm.vue';
import LoadingPage from '@/components/display/loading/LoadingPage.vue';
import Button from '@/components/basic/Button.vue';
import CommonRoot from '@/components/dialog/CommonRoot.vue';
import FlexCol from '@/components/layout/FlexCol.vue';
import Height from '@/components/layout/space/Height.vue';
import XBarSpace from '@/components/layout/space/XBarSpace.vue';
import Alert from '@/components/feedback/Alert.vue';
import type { IDynamicFormOptions, IDynamicFormRef } from '@/components/dynamic';
import type { UploaderFieldInstance } from '@/components/form/UploaderField.vue';
import CommonTopBanner from '@/common/components/CommonTopBanner.vue';
import ProvideVar from '@/components/theme/ProvideVar.vue';
import BackgroundBox from '@/components/display/block/BackgroundBox.vue';
import BackgroundImageButton from '@/components/basic/BackgroundImageButton.vue';
import PrimaryButton from '@/common/components/PrimaryButton.vue';

const loading = ref(false);
const subTitle = ref('');

const formRef = ref<IDynamicFormRef>();
const formModel = ref(new CommonInfoModel()) as Ref<CommonInfoModel>;
const formDefine = ref<IDynamicFormOptions>({
  formItems: [],
  formAdditionaProps: {
    labelWidth: '220rpx',
    labelAlign: 'left',
    innerStyle: {
      borderRadius: '20rpx',
      overflow: 'hidden',
    },
  },
});
let currentFormInfo : SingleForm|null = null;

const { querys } = useLoadQuerys({ 
  villageId: 0,  
  villageVolunteerId: 0,
  catalogId: 0,
  collectModuleId: 0,
  subId: 0,
  subKey: '',
  subTitle: '',
  id: 0,
  isView: false,
}, async (querys) => {
  loading.value = true;
  if (querys.subTitle) {
    subTitle.value = querys.subTitle;
    uni.setNavigationBarTitle({  title: subTitle.value, })
  }
  if (!formRef.value)
    return;

  let formData = undefined;
  await waitTimeOut(800);

  try {
    currentFormInfo = getVillageInfoForm(querys.collectModuleId, querys.subId);
    const [model, forms] = currentFormInfo;
    formModel.value = new model() as any;
    const formOptions = forms(formRef as any);
    formDefine.value = {
      ...formDefine.value,
      ...formOptions,
      readonly: querys.isView,
      disabled: querys.isView,
    };
    let findId = querys.id;
    if (findId <= 0) {
      if (querys.collectModuleId === CollectableModulesIdMap['overview']) {
        const info = await VillageInfoApi.getInfoByVillageId(querys.villageId);
        console.log(info);
        findId = (info.myOverviewId || info.overviewId) as number;
      }
    }
    if (findId > 0) {
      formData = await VillageInfoApi.getInfo(
        querys.collectModuleId,
        querys.subId,
        querys.subKey,
        querys.villageId, 
        querys.villageVolunteerId,
        querys.catalogId,
        findId,
        model,
      );
    }
  } catch (e) {
    console.log(e);
    if (!(e instanceof RequestApiError && e.errorMessage.startsWith('请完成')))
      showError(e, undefined, () => backPrev(false));
  } finally {
    loading.value = false;
  }

  if (!querys.isView) {
    try {
      formData = await loadLocalSave(formData as CommonInfoModel);
    } catch (e) {
      console.log(e);
      showError(e, '加载本地保存数据失败');
    }
  }
  
  if (formData)
    formModel.value = formData as any;

  await nextTick();
  await waitTimeOut(400);
  formRef.value.initDefaultValuesToModel();

  console.log(formModel.value);

  await waitTimeOut(1000);
  if (!querys.isView)
    canSaveNow = true;
});

const debounceSubmit = new Debounce(1000, submit);

async function submit() {
  if (!formRef.value)
    return;
  try {
    await formRef.value.validate();
  } catch {
    toast('有必填项未填写，请检查');
    return;
  }
  try {
    loading.value = true;

    // 检查是否有上传中的文件
    const controls = formRef.value.getFormItemControlRefsByType<UploaderFieldInstance>('uploader');
    if (controls.filter(c => c.getUploaderRef()?.isAnyUploading()).length > 0) {
      await alert({
        content: '您有未上传完成的文件，请等待上传完成',
        icon: 'prompt',
      });
      return;
    }

    // 提交表单数据
    await waitTimeOut(800);
    await VillageInfoApi.updateInfo(
      querys.value.collectModuleId,
      querys.value.subKey,
      querys.value.subId,
      querys.value.villageId,
      querys.value.villageVolunteerId,
      querys.value.catalogId,
      formModel.value as CommonInfoModel,
    );
    deleteLocalSave();
    confirm({
      content: '您的提交已成功，感谢您的参与！',
      cancelText: '继续编辑',
      confirmText: '返回列表',
      icon: 'success',
      onConfirm: () => backPrev(true),
    })
  } catch (e) {
    showError(e);
  } finally {
    await waitTimeOut(2000);
    loading.value = false;
  }
}
function backPrev(needRefresh: boolean) {
  backAndCallOnPageBack('list', {
    needRefresh,
  });
}

async function deleteInfo() {
  const res = await confirm({
    content: '确认要删除该信息吗？删除后将无法恢复请谨慎操作！',
    cancelText: '取消',
    confirmText: '删除',
    confirmColor: 'danger',
    confirmCountDown: 10,
    icon: 'delete-filling',
    iconColor: 'danger',
  });
  if (!res)
    return;
  loading.value = true;
  try {
    await waitTimeOut(800);
    await VillageInfoApi.deleteInfo(querys.value.id);
    toast('删除成功');
    backPrev(true);
  } catch (e) {
    showError(e);
  } finally {
    loading.value = false;
  }
}
const localSavedState = ref(false);
const saveLocalSaveDebounce = new Debounce(1000, saveLocalSave);
let canSaveNow = false;

function getSaveName() {
  return `FormLocalSave-${querys.value.id}-${querys.value.collectModuleId}-${querys.value.subId}-${querys.value.villageId}-${querys.value.villageVolunteerId}`;
}
async function loadLocalSave(formData: CommonInfoModel|undefined) {
  if (!currentFormInfo)
    return formData;
  console.log('加载暂存数据');
  const saveName = getSaveName();
  const saveData = uni.getStorageSync(saveName);
  if (saveData) {
    const res = await confirm({
      content: '您有上次编辑未完成的内容，是否要从上次的编辑数据继续？',
      cancelText: '取消',
      confirmText: '继续',
      icon: 'prompt',
    })
    if (res) {
      const d = JSON.parse(saveData);
      d.id = 0;
      formData = new currentFormInfo[0]().fromServerSide(d) as CommonInfoModel;  
      console.log('有暂存数据', formData);
    } else
      deleteLocalSave();
  }
  return formData;
}
function deleteLocalSave() {
  const saveName = getSaveName();
  uni.removeStorageSync(saveName);
  localSavedState.value = false;
}
function saveLocalSave() {
  const saveName = getSaveName();
  uni.setStorageSync(saveName, JSON.stringify(formModel.value.toServerSide()));
  localSavedState.value = true;
  console.log('保存暂存数据');
}

watch(formModel, () => {
  if (!canSaveNow)
    return;
  saveLocalSaveDebounce.executeWithDelay();
}, { deep: true })
</script>
