import { defineComponent } from '@vue/composition-api';
import { publishAndSyncVideo } from '@/api/shopee/seller/video';
import {
  apiShopeeVideoItemBulkCreate,
  apiShopeeVideoItemUpdate,
  apiShopeeVideoUploadR2,
} from '@/api/autoshopee/shopee/shopeeVideo';
import { loggerShopee } from '@/plugins/logger';

const COLOR = {
  pending: '#ff9900',
  success: '#19be6b',
  error: '#ed4014',
};

export default defineComponent({
  data() {
    return {
      products: [],
      caption: '',
      publishing: false,
      savingDraft: false,
      draftSaved: false,
      published: false,
      publishedVideoId: '',
      attempted: false,
      logText: '',
      logColor: COLOR.pending,
    };
  },
  computed: {
    isBusy() {
      return this.publishing || this.savingDraft;
    },
    hasProducts() {
      return this.products.length > 0;
    },
    hasCaption() {
      return !!this.caption.trim();
    },
    requirements() {
      return [
        { key: 'campaign', label: this.$t('SHOPEE_VIDEO_REQ_CAMPAIGN'), done: this.hasCampaign },
        { key: 'products', label: this.$t('SHOPEE_VIDEO_REQ_PRODUCTS'), done: this.hasProducts },
        { key: 'caption', label: this.$t('SHOPEE_VIDEO_REQ_CAPTION'), done: this.hasCaption },
      ];
    },
    canSaveDraft() {
      return !!(this.hasCampaign && this.videoUrl && !this.isBusy && !this.draftSaved && !this.published);
    },
    canPublish() {
      return !!(
        this.hasCampaign
        && this.hasProducts
        && this.hasCaption
        && this.videoUrl
        && !this.isBusy
        && !this.published
      );
    },
  },
  methods: {
    /**
     * @returns {Promise<string>}
     */
    async resolveStoredSourceUrl() {
      const fallback = this.sourceUrl || this.videoUrl;

      if (this.source !== 'tiktok' || !this.videoBlob) {
        return fallback;
      }

      const fileName = `tiktok-${Date.now()}.mp4`;
      const r2Url = await apiShopeeVideoUploadR2(this.videoBlob, fileName);

      return r2Url || fallback;
    },
    async saveDraft() {
      if (!this.canSaveDraft) {
        return;
      }

      this.savingDraft = true;
      this.logText = this.$t('SHOPEE_VIDEO_DRAFT_PROCESSING');
      this.logColor = COLOR.pending;

      try {
        const campaignId = await this.resolveCampaignId();

        if (!campaignId) {
          throw new Error('SHOPEE_VIDEO_NO_CAMPAIGN');
        }

        const storedUrl = await this.resolveStoredSourceUrl();

        const created = await apiShopeeVideoItemBulkCreate(campaignId, [
          {
            source: this.source,
            sourceUrl: storedUrl,
            caption: this.caption,
            products: this.products,
            status: 'draft',
          },
        ]);

        if (!(created && created.length)) {
          throw new Error('SHOPEE_VIDEO_DRAFT_EMPTY');
        }

        this.draftSaved = true;
        this.logText = this.$t('SHOPEE_VIDEO_DRAFT_SUCCESS');
        this.logColor = COLOR.success;
      } catch (error) {
        loggerShopee.error({
          msg: 'SHOPEE_VIDEO_DRAFT_ERROR',
          error,
        });
        this.logText = this.$t('SHOPEE_VIDEO_DRAFT_ERROR');
        this.logColor = COLOR.error;
      }

      this.savingDraft = false;
    },
    async publish() {
      if (!this.canPublish) {
        this.attempted = true;
        this.$Message.warning(this.$t('SHOPEE_VIDEO_PUBLISH_REQUIRE'));
        return;
      }

      this.publishing = true;
      this.logColor = COLOR.pending;
      this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_STEP_PREPARE');

      const campaignId = await this.resolveCampaignId();

      if (!campaignId) {
        this.logText = this.$t('SHOPEE_VIDEO_CAMPAIGN_CREATE_ERROR');
        this.logColor = COLOR.error;
        this.publishing = false;
        return;
      }

      if (this.source === 'tiktok' && this.videoBlob) {
        this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_STEP_R2');
      }

      const storedUrl = await this.resolveStoredSourceUrl();

      const created = await apiShopeeVideoItemBulkCreate(campaignId, [
        {
          source: this.source,
          sourceUrl: storedUrl,
          caption: this.caption,
          products: this.products,
        },
      ]);

      const itemId = created && created[0] ? created[0]._id : '';

      try {
        let blob = this.videoBlob;

        if (!blob) {
          const response = await fetch(this.videoUrl);
          blob = await response.blob();
        }

        const productList = this.products.map((product) => {
          return {
            itemId: Number(product.itemId),
            name: product.name,
            cover: product.cover,
            minPrice: product.snapshot.minPrice,
            maxPrice: product.snapshot.maxPrice,
            status: product.snapshot.status,
            stock: product.snapshot.stock,
            shopId: Number(this.shopId),
          };
        });

        this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_STEP_UPLOAD');

        const { vid, videoId: shopeeVideoId, infoPatch } = await publishAndSyncVideo(
          blob,
          {
            caption: this.caption,
            productList,
          },
          () => {
            this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_STEP_VIDEOID');
          },
        );

        if (itemId) {
          await apiShopeeVideoItemUpdate(itemId, {
            status: 'done',
            mmsVid: vid,
            videoId: shopeeVideoId,
            postedAt: new Date().toISOString(),
            ...infoPatch,
          });
        }

        this.published = true;
        this.publishedVideoId = shopeeVideoId;
        this.logColor = COLOR.success;

        if (shopeeVideoId) {
          this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_SUCCESS_ID', { videoId: shopeeVideoId });
          this.$Message.success(this.$t('SHOPEE_VIDEO_PUBLISH_SUCCESS_ID', { videoId: shopeeVideoId }));
        } else {
          this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_SUCCESS');
          this.$Message.success(this.$t('SHOPEE_VIDEO_PUBLISH_SUCCESS'));
        }

        this.$router.push({ name: 'ShopeeVideoDashboard' });
      } catch (error) {
        loggerShopee.error({
          msg: 'SHOPEE_VIDEO_PUBLISH_ERROR',
          error,
        });

        if (itemId) {
          await apiShopeeVideoItemUpdate(itemId, {
            status: 'error',
            errorMsg: `${error && error.message ? error.message : error}`.slice(0, 200),
          });
        }

        this.logText = this.$t('SHOPEE_VIDEO_PUBLISH_ERROR');
        this.logColor = COLOR.error;
      }

      this.publishing = false;
    },
  },
});
