<template>
  <!--TODO: 在uniapp插槽问题修复后，此处可修改为插槽默认值-->
  <FlexCol :innerStyle="{ 
    ...themeStyles.dialog.value, 
    width: themeContext.resolveThemeSize(width) 
  }">
    <slot v-if="topSlots?.default" />
    <FlexCol v-else :padding="contentPadding" align="center">
      <!-- 图标 -->
      <FlexCol v-if="icon" :innerStyle="themeStyles.icon.value">
        <slot name="icon" :icon="icon" />
        <Icon :icon="icon" :color="iconColor" :size="iconSize || 40" />
      </FlexCol>
      <!-- 标题 -->
      <slot v-if="topSlots?.title" name="title" :title="title" />
      <text v-else-if="title" :style="themeStyles.title.value">{{ title }}</text>

      <!-- 内容 -->
      <scroll-view 
        v-if="contentScroll" 
        scroll-y
        scroll-x
        :style="{
          position: 'relative',
          maxHeight: contentScrollMaxHeight
        }"
      >
        <slot v-if="topSlots?.content" name="content" />
        <text :style="themeStyles.contentText.value">{{ content }}</text>
      </scroll-view>
      <template v-else>
        <slot v-if="topSlots?.content" name="content" />
        <text v-else :style="themeStyles.contentText.value">{{ content }}</text>
      </template>
    </FlexCol>
    <!-- 底部按钮 -->
    <slot 
      v-if="topSlots?.bottomContent"
      name="bottomContent" 
      :onConfirmClick="(name?: string) => onConfirmClick(name || 'confirm')" 
      :onCancelClick="onCancelClick"
    />
    <FlexView v-else :direction="bottomVertical ? 'column' : 'row'" :innerStyle="themeStyles.bottomView.value">
      <DialogButton
        v-if="showCancel"
        key="cancel"
        :vertical="bottomVertical"
        :text="cancelText"
        :loading="buttomLoadingState.cancel"
        :buttonColor="cancelColor"
        @click="onCancelClick"
      />
      <DialogButton
        v-for="(button, key) in customButtons"
        :vertical="bottomVertical"
        :key="key"
        :text="button.text"
        :loading="buttomLoadingState[button.name]"
        :buttonColor="button.color || 'text.content'"
        @click="onConfirmClick(button.name)"
      />
      <DialogButton
        v-if="showConfirm"
        key="confirm"
        :vertical="bottomVertical"
        :text="confirmCountDownValue > 0 ? `${confirmText} (${confirmCountDownValue})` : confirmText"
        :loading="buttomLoadingState.confirm"
        :touchable="confirmCountDownValue <= 0"
        :buttonColor="confirmColor"
        @click="onConfirmClick('confirm')"
      />
    </FlexView>
  </FlexCol>
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { propGetThemeVar, useTheme } from '../theme/ThemeDefine';
import { DynamicColor, DynamicSize, DynamicVar } from '../theme/ThemeTools';
import FlexView from '../layout/FlexView.vue';
import FlexCol from '../layout/FlexCol.vue';
import Icon from '../basic/Icon.vue';
import DialogButton from './DialogButton.vue';
import type { DialogProps } from './Dialog.vue';

const themeContext = useTheme();
const themeStyles = themeContext.useThemeStyles({
  dialog: {
    minWidth: DynamicSize('DialogMinWidth', 400),
    maxWidth: DynamicSize('DialogMaxWidth', 700),
  },
  bottomView: {
    position: 'relative',
  },
  icon: {
    marginTop: DynamicSize('DialogIconMarginTop', 16),
    marginBottom: DynamicSize('DialogIconMarginBottom', 12),
    justifyContent: 'center',
    alignItems: 'center',
  },
  title: {
    fontSize: DynamicSize('DialogTitleFontSize', 36),
    color: DynamicColor('DialogTitleColor', 'text.content'),
    fontWeight: DynamicSize('DialogTitleFontWeight', 'bold'),
    textAlign: 'center',
    marginBottom: DynamicSize('DialogTitleMarginBottom', 20),
  },
  contentText: {
    width: '100%',
    display: 'block',
    fontSize: DynamicSize('DialogContentTextFontSize', 28),
    color: DynamicColor('DialogContentTextColor', 'text.second'),
    textAlign: DynamicVar('DialogContentTextAlign', 'center'),
  },
});

export interface DialogInnerProps extends Omit<DialogProps, 'show'> {
  topSlots?: Record<string, boolean>,
  confirmCountDownTime?: number,
}

const emit = defineEmits([ 'close' ]);

const props = withDefaults(defineProps<DialogInnerProps>(), {
  showConfirm: true,
  cancelText: '取消',
  cancelColor: () => propGetThemeVar('DialogCancelColor', 'text.content'),
  confirmText: '确定',
  confirmColor: () => propGetThemeVar('DialogConfirmColor', 'primary'),
  iconSize: () => propGetThemeVar('DialogIconSize', 70),
  iconColor: () => propGetThemeVar('DialogIconColor', 'primary'),
  contentScroll: true,
  contentScrollMaxHeight: () => propGetThemeVar('DialogContentScrollMaxHeight', '1000rpx'),
  contentPadding: () => propGetThemeVar('DialogContentPadding', [ 30, 40 ]),
});

const buttomLoadingState = ref<Record<string, boolean>>({});
const confirmCountDownValue = ref<number>(0);

function setButtonLoadingStateByName(name: string, state: boolean) {
  buttomLoadingState.value[name] = state;
}
function checkAnyButtonLoading() {
  for (const key in buttomLoadingState.value) {
    if (buttomLoadingState.value[key] === true)
      return true;
  }
  return false;
}
function startConfirmCountDown() {
  if (!props.confirmCountDownTime)
    return;
  confirmCountDownValue.value = props.confirmCountDownTime;
  const interval = setInterval(() => {
    confirmCountDownValue.value--;
    if (confirmCountDownValue.value <= 0) {
      clearInterval(interval);
    }
  }, 1000);
}
  
function onPopupClose() {
  emit('close');
}
function onCancelClick() {  
  if (checkAnyButtonLoading())
    return;
  if (!props.onCancel) {
    onPopupClose();
    return;
  }
  const ret = props.onCancel();
  if (typeof ret === 'object') {
    setButtonLoadingStateByName('cancel', true);
    ret.then(() => {
      setButtonLoadingStateByName('cancel', false);
      onPopupClose();
    }).catch(() => {
      setButtonLoadingStateByName('cancel', false);
    });
  } else onPopupClose();
}
function onConfirmClick(name: string) {
  if (checkAnyButtonLoading())
    return;
  if (!props.onConfirm) {
    onPopupClose();
    return;
  }
  const ret = props.onConfirm(name);
  if (typeof ret === 'object') {
    setButtonLoadingStateByName(name, true);
    ret.then(() => {
      setButtonLoadingStateByName(name, false);
      onPopupClose();
    }).catch(() => {
      setButtonLoadingStateByName(name, false);
    });
  } else onPopupClose();
}

onMounted(() => {
  setTimeout(() => {
    startConfirmCountDown();
  }, 200);
});
defineExpose({
  startConfirmCountDown,
})

</script>