<script setup lang="ts" generic="T extends Record<string, any>">
import { computed, ref, useTemplateRef } from 'vue';
import { useRouter } from 'vue-router';

import SvgIcon from '@/components/SvgIcon.vue';
import { t } from '@/i18n';
import { addUnit } from '@/utils';

import type { CSSProperties } from 'vue';
import type { FormInstance } from 'ant-design-vue';
import type { FormRules, UseGuideStepItem, UseGuideStepItemInstance } from '@/types';

interface Props {
  title: string;
  steps: UseGuideStepItem[];
  form: T;
  rules: FormRules<T>;
  contentOffset?: number;
  headerMargin?: number;
}

const props = defineProps<Props>();

const router = useRouter();
const current = ref(0);

const currentStep = computed(() => {
  return props.steps[current.value];
});

const isFirstStep = computed(() => {
  return current.value === 0;
});

const contentStyle = computed<CSSProperties>(() => {
  // const contentOffset = props.steps[current.value].contentOffset ?? props.contentOffset;

  return {
    // paddingLeft: addUnit(contentOffset ?? 312),
  };
});

const headerStyle = computed<CSSProperties>(() => {
  const dividerWidth = currentStep.value.hideHeaderDivider ? 0 : 1;
  const headerMargin = currentStep.value.headerMargin ?? props.headerMargin;

  return {
    borderBottomWidth: addUnit(dividerWidth),
    marginBottom: addUnit(headerMargin ?? 40),
  };
});

const goToStep = (index: number) => {
  current.value = index;
};

const goNextStep = () => {
  current.value++;
};

const goPrevStep = () => {
  if (isFirstStep.value) {
    router.replace('/first-usage');
    return;
  }

  current.value--;
};

const formRef = ref<FormInstance>();
const stepRef = useTemplateRef<UseGuideStepItemInstance>('stepItem');

const exportStepContent = async () => {
  await stepRef.value?.exportData?.();
};

const finishCurrentStep = async () => {
  try {
    await formRef.value?.validate();
    await stepRef.value?.finish?.();

    if (currentStep.value.isLastStep) {
      router.replace('/first-usage');
    } else {
      goNextStep();
    }
  } catch (err) {
    console.error(err);
  }
};
</script>

<template>
  <ALayout class="use-guide-container">
    <ALayoutSider class="use-guide-sider" :width="268">
      <div class="use-guide-title">{{ title }}</div>
      <div class="use-guide-steps">
        <ASteps :current="current" :items="steps" direction="vertical" />
      </div>
      <AButton class="icon-button doc-button">
        <SvgIcon name="eye-o" />
        {{ $t('common.viewDoc') }}
      </AButton>
    </ALayoutSider>
    <ALayout>
      <ALayoutContent class="use-guide-main" :style="contentStyle">
        <div v-show="!currentStep.hideHeader" class="step-header" :style="headerStyle">
          <div class="step-title">{{ currentStep.stepTitle || currentStep.title }}</div>
          <div class="step-description">{{ currentStep.stepDescription }}</div>
        </div>
        <AForm
          ref="formRef"
          :model="form"
          :rules="rules"
          :layout="currentStep.formLayout"
          :label-align="currentStep.labelAlign"
          :label-col="currentStep.labelCol"
          :wrapper-col="currentStep.wrapperCol"
          :colon="false"
        >
          <component
            ref="stepItem"
            :is="currentStep.component"
            :form="form"
            :steps="steps"
            :step-index="current"
            :go-to-step="goToStep"
          />
        </AForm>
      </ALayoutContent>
      <ALayoutFooter class="use-guide-footer">
        <div class="use-guide-step-button-container">
          <div>
            <AButton type="text" :disabled="currentStep.isLastStep" @click="goNextStep">
              {{ $t('common.skip') }}
            </AButton>
            <AButton type="text" @click="goPrevStep">{{ $t('common.return') }}</AButton>
          </div>
          <div>
            <AButton v-if="currentStep.exportButtonShow" class="icon-button export-button" @click="exportStepContent">
              <SvgIcon name="download" />
              {{ $t('common.exportToLocal') }}
            </AButton>
            <AButton
              v-show="!currentStep.nextStepButtonHide"
              class="next-step-button"
              type="primary"
              :disabled="currentStep.nextStepButtonDisabled"
              @click="finishCurrentStep"
            >
              {{ currentStep.nextStepButtonText || t('common.nextStep') }}
            </AButton>
          </div>
        </div>
      </ALayoutFooter>
    </ALayout>
  </ALayout>
</template>

<style lang="scss" scoped>
.use-guide-container {
  height: 100%;
}

.use-guide-sider {
  padding-top: 48px;
  padding-bottom: 40px;
  background: #f0f0f0;

  :deep(.ant-layout-sider-children) {
    display: flex;
    flex-direction: column;
    align-items: center;
  }

  .use-guide-title {
    margin-bottom: 32px;
    text-align: center;
  }

  .use-guide-steps {
    flex: 1;
  }

  :deep(.ant-steps) {
    .ant-steps-item {
      height: 80px;
    }

    .ant-steps-item-wait {
      .ant-steps-item-icon {
        background-color: initial;
        border-color: var(--antd-color-fill);
      }

      .ant-steps-icon {
        color: var(--antd-color-text-quaternary);
      }
    }

    .ant-steps-item-process {
      .ant-steps-item-title {
        font-weight: 500;
      }
    }

    .ant-steps-item-finish {
      .ant-steps-item-icon {
        background-color: initial;
        border-color: var(--antd-color-primary);
      }

      .ant-steps-item-title {
        color: var(--antd-color-text-secondary);
      }
    }

    .ant-steps-item-process,
    .ant-steps-item-wait {
      .ant-steps-item-tail::after {
        background-color: var(--antd-color-fill);
      }
    }
  }

  .doc-button {
    width: 120px;
    height: 40px;
  }
}

.use-guide-main {
  padding: 40px;
  padding-bottom: 0;
  overflow: auto;
  background: var(--antd-color-bg-base);

  .step-header {
    padding-bottom: 40px;
    border-bottom: 1px solid #e4e7ed;
  }

  .step-title {
    margin-bottom: 8px;
    font-size: 20px;
    font-weight: 500;
    line-height: 28px;
    color: var(--antd-color-text);
  }

  .step-description {
    min-height: 22px;
    font-size: 14px;
    line-height: 22px;
    color: var(--antd-color-text-secondary);
  }
}

.use-guide-footer {
  padding-inline: 40px;
  background: var(--antd-color-bg-base);
}

.use-guide-step-button-container {
  display: flex;
  justify-content: space-between;
  max-width: 686px;

  button {
    height: 40px;
  }

  .ant-btn-text {
    width: 80px;
  }

  .export-button {
    width: 136px;
    margin-right: 16px;
  }

  .next-step-button {
    width: 128px;
    font-size: 16px;
  }
}
</style>
