<template>
  <div class="pdf-print-container">
    <Row :gutter="24">
      <Col
        :span="isPopup ? 24 : 10"
        class="pdf-config-section"
      >
        <Card
          dis-hover
          :bordered="false"
          class="config-card"
        >
          <div class="card-header">
            <div
              v-if="pdfLoading"
              class="loading-indicator"
            >
              <i class="fa fa-spinner fa-spin" />
              <span class="loading-text">{{ $t('PDF_PRINT_CONFIG.LOADING_FILE') }}</span>
            </div>

            <div
              v-if="!fromFile && !pdfLoading"
              class="session-header"
              v-html="sesionName"
            />
          </div>

          <div
            v-if="fromFile"
            class="upload-section"
          >
            <Upload
              multiple
              type="drag"
              action=""
              accept="application/pdf"
              :before-upload="handleUpload"
              :show-upload-list="false"
            >
              <div class="upload-content">
                <Icon
                  type="ios-cloud-upload"
                  size="64"
                  class="upload-icon"
                />
                <p class="upload-text">
                  {{ fileNameUpload || $t('SESSION_PRINT.UPLOAD_FILE') }}
                </p>
                <p
                  v-if="!fileNameUpload"
                  class="upload-hint"
                >
                  {{ $t('SESSION_PRINT.UPLOAD_HINT') }}
                </p>
              </div>
            </Upload>
          </div>

          <div class="config-section session-config">
            <div class="section-header">
              <div class="header-left">
                <i-switch
                  v-model="sessionPrint.active"
                  size="default"
                />
                <h3 class="section-title">
                  {{ $t('SESSION_PRINT.TITLE') }}
                </h3>
              </div>
            </div>

            <div
              v-if="sessionPrint.active"
              class="config-content"
            >
              <div class="config-options">
                <div class="option-item">
                  <Checkbox
                    v-model="sessionPrint.isPagging"
                    :disabled="!sessionPrint.active"
                  >
                    <span class="option-label">
                      {{ $t("SESSION_PRINT.ACTIVE_PAGGING") }}
                    </span>
                  </Checkbox>
                </div>

                <div class="option-item">
                  <Checkbox
                    v-model="sessionPrint.isTimestamp"
                    :disabled="!sessionPrint.active"
                  >
                    <span class="option-label">
                      {{ $t("SESSION_PRINT.IS_TIMESTAMP") }}
                    </span>
                  </Checkbox>
                </div>
              </div>

              <Row
                :gutter="12"
                class="config-fields"
              >
                <Col :span="12">
                  <div class="field-group">
                    <label class="field-label">
                      {{ $t('SESSION_PRINT.SESSION_NAME') }}
                    </label>
                    <Input
                      v-model="sessionPrint.content"
                      :disabled="!sessionPrint.active"
                      :placeholder="$t('SESSION_PRINT.ENTER_SESSION_NAME')"
                      size="default"
                    />
                  </div>
                </Col>

                <Col :span="7">
                  <div class="field-group">
                    <label class="field-label">
                      {{ $t('PDF_PRINT_CONFIG.POSITION') }}
                    </label>
                    <Select
                      v-model="sessionPrint.position"
                      :disabled="!sessionPrint.active"
                      size="default"
                    >
                      <Option
                        v-for="option in positionOptions"
                        :key="option.value"
                        :value="option.value"
                      >
                        {{ option.emoji }} {{ $t(`PDF_PRINT_CONFIG.${option.label}`) }}
                      </Option>
                    </Select>
                  </div>
                </Col>

                <Col :span="5">
                  <div class="field-group">
                    <label class="field-label">
                      {{ $t('PDF_PRINT_CONFIG.FONT_SIZE') }}
                    </label>
                    <InputNumber
                      v-model="sessionPrint.fontSize"
                      :disabled="!sessionPrint.active"
                      :min="8"
                      :max="72"
                      size="default"
                      style="width: 100%"
                    />
                  </div>
                </Col>
              </Row>
            </div>
          </div>

          <div class="config-section template-section">
            <div
              v-if="listConfig.length"
              class="template-content"
            >
              <div class="section-header-simple">
                <h3 class="section-title">
                  <i class="fa fa-print" />
                  {{ $t('SESSION_PRINT.LIST_TEMPLATE') }}
                </h3>
              </div>

              <div class="template-buttons">
                <Button
                  v-for="item in listConfig"
                  :key="item._id"
                  :type="item.isDefault ? 'default' : 'primary'"
                  size="small"
                  :loading="btnLoading"
                  :disabled="pdfLoading"
                  class="template-button"
                  @click="printPdfConfig(item.config)"
                >
                  <i
                    :class="item.isDefault ? 'fa fa-file-pdf-o' : 'fa fa-print'"
                  />
                  <span>{{ item.name }}</span>
                </Button>
              </div>

              <div class="template-footer">
                <div class="footer-left">
                  <Checkbox
                    v-model="isSaveFile"
                    :value="isSaveFile"
                    @on-change="onChangSaveFile"
                  >
                    <span class="option-label">
                      {{ $t('SESSION_PRINT.IS_SAVE_FILE') }}
                    </span>
                  </Checkbox>
                </div>

                <div class="footer-right">
                  <router-link
                    to="/printer/config"
                    target="_blank"
                    class="create-template-link"
                  >
                    <i class="fa fa-plus-circle" />
                    {{ $t('PDF_PRINT_CONFIG.CREATE_TEMPLATE') }}
                  </router-link>
                </div>
              </div>
            </div>

            <div
              v-else
              class="template-empty"
            >
              <div class="empty-content">
                <i class="fa fa-file-o empty-icon" />
                <p class="empty-text">
                  {{ $t('SESSION_PRINT.TEMPLATE_EMPTY') }}
                </p>
                <router-link
                  to="/printer/config"
                  target="_blank"
                  class="create-template-button"
                >
                  <Button
                    type="primary"
                    size="large"
                  >
                    <i class="fa fa-plus" />
                    {{ $t('PDF_PRINT_CONFIG.CREATE_TEMPLATE_FIRST') }}
                  </Button>
                </router-link>
              </div>
            </div>
          </div>
        </Card>
      </Col>

      <Col
        v-if="!isPopup"
        :span="14"
        class="pdf-preview-section"
      >
        <Card
          dis-hover
          :bordered="false"
          class="preview-card"
        >
          <div class="preview-header">
            <h3 class="preview-title">
              <i class="fa fa-eye" />
              {{ $t('SESSION_PRINT.PREVIEW_TITLE') }}
            </h3>
          </div>

          <div class="preview-content">
            <div
              v-if="pdfFileUploadUrl"
              class="preview-iframe-wrapper"
            >
              <iframe
                :src="pdfFileUploadUrl"
                class="preview-iframe"
                frameborder="0"
              />
            </div>

            <div
              v-else
              class="preview-empty"
            >
              <i class="fa fa-file-pdf-o preview-empty-icon" />
              <p class="preview-empty-text">
                {{ $t('SESSION_PRINT.PREVIEW_EMPTY') }}
              </p>
            </div>
          </div>
        </Card>
      </Col>
    </Row>
  </div>
</template>

<script>
import * as cheerio from 'cheerio';
import { v4 as uuid } from 'uuid';
import { ConfigPdfPrinter } from '@/models/config';
import { saveAsPdf, getUrlBlobPdf } from '@/lib/pdf/api';
import { PdfService } from '@/lib/pdf/service';
import { getShopeePrintPdf } from '@/api/shopee/seller/order/print';
import { CacheOrderPdfBuffer } from '@/plugins/store/cache';
import { usePrinterStore } from '@/vue/pinia/printer';
import { bridgeGetWebcontentTabId } from '@/bridge/options/background';
import { useSessionStorage } from '@vueuse/core';
import { STORAGE_KEYS } from '@/constant/storage';
import { loggerVue } from '@/plugins/logger';
import { getPdfFromUrl } from '@/api/utils/get';

const printerStore = usePrinterStore();

const getIframePdfFromHtml = (html) => {
  const $ = cheerio.load(html);
  const iframe = $('iframe');
  const iframeUrl = iframe.attr('src');
  return iframeUrl;
};

export default {
  name: 'PrinterPDF',
  props: {
    isPopup: {
      type: Boolean,
      default: false,
    },
  },
  data() {
    const listConfig = useSessionStorage(STORAGE_KEYS.SESSION_STORAGE.PRINTER_PDF_LIST_CONFIG, []);

    return {
      btnLoading: false,
      pdfLoading: false,
      shopId: this.$route.query.shopId || '',
      jobId: this.$route.query.jobId || '',
      jobUrl: this.$route.query.jobUrl || '',
      fromTabId: Number(this.$route.query.fromTabId) || 0,
      from: this.$route.query.from || 'file',
      fileNameUpload: '',
      pdfFileUploadUrl: '',
      pdfOrignBuffer: null,
      listConfig,
      isSaveFile: printerStore.saveFilePrint,
      positionOptions: printerStore.listPosition,
      sessionPrint: printerStore.sessionPrint,
    };
  },
  methods: {
    onChangSaveFile() {
      printerStore.saveFilePrint = this.isSaveFile;
    },
    generatePdfBlobUrl(pdfInput) {
      const blob = new Blob([pdfInput], { type: 'application/pdf' });
      return URL.createObjectURL(blob);
    },
    /**
     * @param {File} fileUpload
     */
    async handleUpload(fileUpload) {
      if (!fileUpload) {
        return false;
      }

      this.fileNameUpload = fileUpload.name;
      this.pdfOrignBuffer = await fileUpload.arrayBuffer();
      this.pdfFileUploadUrl = this.generatePdfBlobUrl(this.pdfOrignBuffer);
      this.$Message.success(this.$t('SESSION_PRINT.UPLOAD_FILE_SUCCESS'));
    },
    async pdfFetchFile() {
      this.pdfLoading = true;

      const cacheKey = [this.from, this.jobId, this.jobUrl].join('_');
      const CachePdf = new CacheOrderPdfBuffer(cacheKey);

      const getCachePdf = await CachePdf.get();

      if (!this.jobId) {
        this.jobId = CachePdf.key;
      }

      if (getCachePdf) {
        this.pdfOrignBuffer = new Uint8Array(getCachePdf.buffer).buffer;
      } else {
        try {
          if (this.from === 'shopee' && this.jobId) {
            this.pdfOrignBuffer = await getShopeePrintPdf(this.jobId);

            await CachePdf.set({
              buffer: Array.from(new Uint8Array(this.pdfOrignBuffer)),
            });
          }

          if (this.from === 'tiktok' && this.jobUrl) {
            this.pdfOrignBuffer = await getPdfFromUrl(this.jobUrl);

            await CachePdf.set({
              buffer: Array.from(new Uint8Array(this.pdfOrignBuffer)),
            });
          }

          if (this.from === 'url' && this.jobUrl) {
            this.pdfOrignBuffer = await getPdfFromUrl(this.jobUrl);

            await CachePdf.set({
              buffer: Array.from(new Uint8Array(this.pdfOrignBuffer)),
            });
          }

          if (this.from === 'lazada' && this.jobUrl) {
            const tabId = this.fromTabId;

            const html = await bridgeGetWebcontentTabId(tabId);

            const iframeUrl = getIframePdfFromHtml(html);
            const pdfUrl = `https://sellercenter.lazada.vn/${iframeUrl}`;

            this.pdfOrignBuffer = await getPdfFromUrl(pdfUrl);

            await CachePdf.set({
              buffer: Array.from(new Uint8Array(this.pdfOrignBuffer)),
            });
          }
        } catch (error) {
          loggerVue.error({
            msg: 'PDF_GET_BUFFER_ERROR',
            from: this.from,
            error,
          });
        }
      }

      if (this.pdfOrignBuffer && !this.pdfFileUploadUrl) {
        this.pdfFileUploadUrl = this.generatePdfBlobUrl(this.pdfOrignBuffer);
      }

      this.pdfLoading = false;
    },
    async printPdfConfig(printConfig) {
      this.btnLoading = true;

      if (!this.pdfOrignBuffer) {
        this.$Message.error(this.$t('SESSION_PRINT.UPLOAD_FILE_NOT_FOUND'));
        this.btnLoading = false;
        return false;
      }

      let pdfBuffer = this.pdfOrignBuffer;

      const pdfService = new PdfService(pdfBuffer);
      try {
        if (printConfig) {
          pdfBuffer = await pdfService.addConfigContent(printConfig);
        }

        if (this.sessionPrint.active) {
          pdfService.setPdfBytes(pdfBuffer);
          pdfBuffer = await pdfService.addFooterContent(this.sessionPrint);
        }

        await this.openPdf(pdfBuffer);
        this.$Message.success(this.$t('SESSION_PRINT.PRINT_SUCCESS'));
      } catch (error) {
        loggerVue.error({
          msg: 'PRINT_PDF_ERROR',
          error,
        });
        this.$Message.error(this.$t('SESSION_PRINT.PRINT_ERROR'));
      }
      this.btnLoading = false;
    },

    async openPdf(pdfBuffer) {
      if (this.isSaveFile) {
        const pdfFileName = `print_${new Date().getTime()}_${this.jobId || uuid()}.pdf`;
        return saveAsPdf(pdfBuffer, pdfFileName);
      }

      const pdfUrl = getUrlBlobPdf(pdfBuffer);

      const windowLoadPdf = window.open(pdfUrl, '_blank');

      windowLoadPdf.onload = () => {
        windowLoadPdf.print();
      };
    },

    async loadConfigs() {
      const listConfig = await ConfigPdfPrinter.findAll();

      if (!listConfig.length) {
        this.listConfig = [];
        return;
      }

      this.listConfig = [
        {
          _id: 'default',
          isDefault: true,
          name: this.$t('PDF_PRINT_CONFIG.DEFAULT_NAME'),
          config: null,
        },
        ...listConfig.filter((item) => {
          return {
            ...item,
            isDefault: false,
          };
        }),
      ];
    },
    async loadPdfFromFile() {
      const urlBlob = '';
      const response = await fetch(urlBlob);
      const blob = await response.blob();
      const url = URL.createObjectURL(blob);

      return this.openExternalUrl(url, false);
    },
  },
  async created() {
    this.loadConfigs();
    ConfigPdfPrinter.pullRemote();

    if (['shopee', 'tiktok', 'lazada', 'url'].includes(this.from)) {
      this.pdfFetchFile();
    } else {
      this.from = 'file';
    }
  },
  computed: {
    fromFile() {
      return this.from === 'file';
    },
    sesionName() {
      return [
        `<span>[${this.from.toUpperCase()}] ${this.$t('SESSION_PRINT.SESSION_NAME')}</span>:`,
        this.jobId,
      ].join(' ');
    },
  },
};
</script>

<style lang="scss" scoped>
.pdf-print-container {
  padding: 16px;
  background: #f5f7fa;
}

.pdf-config-section,
.pdf-preview-section {
  height: 100%;
}

.config-card,
.preview-card {
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
  overflow: hidden;

  :deep(.ivu-card-body) {
    padding: 0;
  }
}

.card-header {
  padding: 20px 24px;
  border-bottom: 1px solid #e8eaed;
  background: #fff;
}

.loading-indicator {
  display: flex;
  align-items: center;
  gap: 12px;
  color: #2d8cf0;
  font-size: 16px;

  i {
    font-size: 20px;
  }

  .loading-text {
    font-weight: 500;
  }
}

.session-header {
  font-size: 15px;
  color: #333;
  font-weight: 500;

  :deep(span) {
    color: #2d8cf0;
  }
}

.upload-section {
  padding: 24px;
  background: #fff;
  border-bottom: 1px solid #e8eaed;

  .upload-content {
    padding: 40px 20px;
    text-align: center;
  }

  .upload-icon {
    color: #2d8cf0;
    margin-bottom: 16px;
  }

  .upload-text {
    font-size: 16px;
    color: #333;
    font-weight: 500;
    margin-bottom: 8px;
  }

  .upload-hint {
    font-size: 13px;
    color: #999;
    margin-top: 8px;
  }

  :deep(.ivu-upload-drag) {
    border: 2px dashed #d9d9d9;
    border-radius: 8px;
    background: #fafafa;
    transition: all 0.3s;

    &:hover {
      border-color: #2d8cf0;
      background: #f0f7ff;
    }
  }
}

.config-section {
  padding: 16px;
  background: #fff;
  border-bottom: 1px solid #e8eaed;

  &:last-child {
    border-bottom: none;
  }
}

.section-header {
  margin-bottom: 12px;

  .header-left {
    display: flex;
    align-items: center;
    gap: 8px;
  }

  .section-title {
    font-size: 14px;
    font-weight: 600;
    color: #333;
    margin: 0;
  }
}

.section-header-simple {
  margin-bottom: 12px;

  .section-title {
    display: flex;
    align-items: center;
    gap: 6px;
    font-size: 14px;
    font-weight: 600;
    color: #333;
    margin: 0;

    i {
      color: #2d8cf0;
    }
  }
}

.config-content {
  margin-top: 12px;
}

.config-options {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 12px;

  .option-item {
    :deep(.ivu-checkbox-wrapper) {
      font-size: 13px;
    }

    .option-label {
      color: #666;
      font-size: 13px;
    }
  }
}

.config-fields {
  margin-top: 12px;
}

.field-group {
  .field-label {
    display: block;
    margin-bottom: 8px;
    font-size: 13px;
    font-weight: 500;
    color: #666;
  }

  :deep(.ivu-input),
  :deep(.ivu-select),
  :deep(.ivu-input-number) {
    border-radius: 6px;
  }
}

.template-section {
  .template-content {
    .template-buttons {
      display: grid;
      grid-template-columns: repeat(4, 1fr);
      gap: 6px;
      margin-bottom: 20px;

      .template-button {
        border-radius: 6px;
        height: 32px;
        font-size: 12px;

        i {
          margin-right: 4px;
        }

        &:deep(.ivu-btn) {
          width: 100%;
        }
      }
    }

    .template-footer {
      display: flex;
      align-items: center;
      justify-content: space-between;
      padding-top: 16px;
      border-top: 1px solid #e8eaed;

      .footer-left {
        .option-label {
          color: #666;
          font-size: 14px;
        }
      }

      .footer-right {
        .create-template-link {
          display: inline-flex;
          align-items: center;
          gap: 6px;
          color: #2d8cf0;
          font-size: 14px;
          font-weight: 500;
          text-decoration: none;
          transition: all 0.3s;

          &:hover {
            color: #1c6bbf;
          }

          i {
            font-size: 14px;
          }
        }
      }
    }
  }

  .template-empty {
    .empty-content {
      text-align: center;
      padding: 60px 20px;

      .empty-icon {
        font-size: 64px;
        color: #d9d9d9;
        margin-bottom: 16px;
      }

      .empty-text {
        font-size: 15px;
        color: #999;
        margin-bottom: 24px;
      }

      .create-template-button {
        display: inline-block;

        :deep(.ivu-btn) {
          border-radius: 6px;
          height: 44px;
          padding: 0 32px;

          i {
            margin-right: 6px;
          }
        }
      }
    }
  }
}

.preview-card {
  height: calc(100vh - 32px);
  display: flex;
  flex-direction: column;

  :deep(.ivu-card-body) {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
  }
}

.preview-header {
  padding: 20px 24px;
  border-bottom: 1px solid #e8eaed;
  background: #fff;

  .preview-title {
    display: flex;
    align-items: center;
    gap: 8px;
    font-size: 16px;
    font-weight: 600;
    color: #333;
    margin: 0;

    i {
      color: #2d8cf0;
    }
  }
}

.preview-content {
  flex: 1;
  background: #f5f5f5;
  display: flex;
  flex-direction: column;
  overflow: hidden;

  .preview-iframe-wrapper {
    flex: 1;
    padding: 16px;
    overflow: hidden;

    .preview-iframe {
      width: 100%;
      height: 100%;
      border-radius: 8px;
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
      background: #fff;
    }
  }

  .preview-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    padding: 40px;

    .preview-empty-icon {
      font-size: 80px;
      color: #d9d9d9;
      margin-bottom: 16px;
    }

    .preview-empty-text {
      font-size: 15px;
      color: #999;
    }
  }
}

@media (max-width: 1200px) {
  .template-buttons {
    grid-template-columns: repeat(3, 1fr) !important;
  }
}

@media (max-width: 768px) {
  .pdf-print-container {
    padding: 8px;
  }

  .config-section {
    padding: 16px;
  }

  .template-buttons {
    grid-template-columns: repeat(2, 1fr) !important;
  }

  .template-footer {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start !important;
  }
}
</style>
