<script setup lang="ts">
import { getPrintContainer, doPrint, doPrintOnFrame, mergeOptions, usePrinter } from './util'
import type { PrintOption } from './types'
import { printerEmits } from './props'
import type { PrinterProps } from './props'

const props = withDefaults(defineProps<PrinterProps>(), {})

const emits = defineEmits(printerEmits)

const { printId } = usePrinter(() => {
  updateModelValue(false)
  onDone()
})

/** 打印容器 */
const container = shallowRef<Element>(getPrintContainer())

/** 是否显示 */
const visible = ref<boolean>(false)

/** 是否显示在文档流中 */
const isStatic = computed<boolean>(() => {
  return props.static
})

/** 打印 */
const print = (options?: any) => {
  visible.value = true
  nextTick(() => {
    const option: PrintOption = {
      printId,
      title: props.title,
      margin: props.margin,
      direction: props.direction,
      orientation: props.orientation,
      options: mergeOptions(props.options, options)
    }
    if (props.target === '_iframe') {
      doPrintOnFrame(option)
      visible.value = false
    } else {
      doPrint(option)
      visible.value = false
      updateModelValue(false)
      onDone()
    }
  })
}

/** 打印完成事件 */
const onDone = () => {
  emits('done')
}

/** 更新绑定值 */
const updateModelValue = (value: boolean) => {
  emits('update:modelValue', value)
}

watch(
  () => props.modelValue,
  value => {
    if (value) {
      print()
    }
  },
  { immediate: true }
)

defineExpose({
  print
})
</script>

<template>
  <Teleport :to="container" :disabled="isStatic && !visible">
    <table :class="['custom-printer', { 'is-open': visible }, { 'is-static': isStatic }]">
      <thead v-if="$slots.header">
        <tr>
          <td>
            <div class="custom-printer-header" :style="headerStyle">
              <slot name="header"></slot>
            </div>
          </td>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td>
            <div class="custom-printer-body" :style="bodyStyle">
              <slot></slot>
            </div>
          </td>
        </tr>
      </tbody>
      <!-- <tfoot v-if="$slots.footer">
        <tr>
          <td>
            <div class="custom-printer-footer" :style="footerStyle">
              <slot name="footer"></slot>
            </div>
          </td>
        </tr>
      </tfoot> -->
    </table>
  </Teleport>
</template>

<style lang="scss">
/* 打印容器 */
#custom-printer-container {
  pointer-events: none;
  display: none;
}

/* 页眉页脚 */
.custom-printer {
  width: 100%;
  border-spacing: 0;
  border-collapse: collapse;
  table-layout: fixed;

  & > thead > tr > td,
  & > tbody > tr > td,
  & > tfoot > tr > td {
    padding: 0;
    border: none;
  }

  &:not(.is-open):not(.is-static) {
    display: none;
  }

  .custom-printer-header,
  .custom-printer-footer {
    display: flex;
    justify-content: space-between;
    box-sizing: border-box;
  }

  &:not(.is-open) .custom-printer-header,
  &:not(.is-open) .custom-printer-footer {
    display: none;
  }

  .custom-printer-body {
    box-sizing: border-box;
  }
}

/* 打印状态 */
html.custom-printing,
html.custom-printing > body {
  color: #000 !important;
  background: #fff !important;
  height: auto !important;
  min-height: auto !important;
  max-height: auto !important;
  width: auto !important;
  min-width: auto !important;
  max-width: auto !important;
  overflow: visible !important;
}

html.custom-printing > body > * {
  display: none !important;
}

html.custom-printing #custom-printer-container {
  display: block !important;

  * {
    pointer-events: none !important;
  }
}
</style>
