<template>
  <div class="sv-bulk">
    <div
      v-if="noShop"
      class="sv-bulk__empty"
    >
      <Icon type="ios-alert-outline" />
      <p>{{ $t('SHOPEE_VIDEO_DASH_NO_SHOP') }}</p>
    </div>

    <div
      v-else
      class="sv-bulk__card"
    >
      <div class="sv-bulk__head">
        <div>
          <h2 class="sv-bulk__title">
            {{ $t('SHOPEE_VIDEO_BULK_TITLE') }}
          </h2>
          <p class="sv-bulk__desc">
            {{ $t('SHOPEE_VIDEO_BULK_DESC') }}
          </p>
        </div>
        <Button
          type="text"
          icon="md-close"
          @click="goDashboard"
        >
          {{ $t('SHOPEE_VIDEO_BULK_CLOSE') }}
        </Button>
      </div>

      <Steps
        :current="step - 1"
        class="sv-bulk__steps"
      >
        <Step :title="$t('SHOPEE_VIDEO_BULK_STEP_SCAN')" />
        <Step :title="$t('SHOPEE_VIDEO_BULK_STEP_SELECT')" />
        <Step :title="$t('SHOPEE_VIDEO_BULK_STEP_REVIEW')" />
      </Steps>

      <div
        v-show="step === 1"
        class="sv-bulk__panel"
      >
        <div class="sv-scan">
          <div class="sv-scan__stat">
            {{ $t('SHOPEE_VIDEO_BULK_SCAN_STAT', { scanned, total }) }}
            ·
            <span class="sv-scan__found">{{ $t('SHOPEE_VIDEO_BULK_SCAN_FOUND', { found: products.length }) }}</span>
          </div>
          <div class="sv-scan__bar">
            <i :style="{ width: `${scanPercent}%` }" />
          </div>
          <div class="sv-scan__ctl">
            <Button
              v-if="!scanning && !scanned"
              type="primary"
              icon="ios-search"
              @click="startScan"
            >
              {{ $t('SHOPEE_VIDEO_BULK_SCAN_START') }}
            </Button>
            <Button
              v-if="scanning"
              icon="md-square"
              @click="stopScan"
            >
              {{ $t('SHOPEE_VIDEO_BULK_SCAN_STOP') }}
            </Button>
            <p
              v-if="!scanning && scanned > 0"
              class="sv-scan__done"
            >
              {{ $t('SHOPEE_VIDEO_BULK_SCAN_DONE', { found: products.length }) }}
            </p>
          </div>
        </div>

        <div class="sv-bulk__foot">
          <span />
          <Button
            type="primary"
            :disabled="!products.length || scanning"
            @click="goStep(2)"
          >
            {{ $t('SHOPEE_VIDEO_BULK_NEXT') }}
          </Button>
        </div>
      </div>

      <div
        v-show="step === 2"
        class="sv-bulk__panel"
      >
        <div class="sv-bulk__selbar">
          <span class="sv-bulk__count">
            {{ $t('SHOPEE_VIDEO_BULK_SELECTED', { selected: selectedProducts.length, total: products.length }) }}
          </span>
          <Button
            type="text"
            size="small"
            @click="toggleSelectAll"
          >
            {{ allSelected ? $t('SHOPEE_VIDEO_BULK_UNSELECT_ALL') : $t('SHOPEE_VIDEO_BULK_SELECT_ALL') }}
          </Button>
        </div>

        <div class="sv-grid">
          <div
            v-for="product in products"
            :key="product.itemId"
            class="sv-pcard"
            :class="{ 'is-selected': product.checked }"
            @click="toggleSelect(product)"
          >
            <div
              class="sv-pcard__thumb"
              :style="thumbStyle(product)"
            >
              <video
                v-if="product.videoUrl"
                class="sv-pcard__video"
                :src="`${product.videoUrl}#t=0.5`"
                muted
                playsinline
                preload="metadata"
              />
              <span class="sv-pcard__vbadge">VIDEO</span>
              <span
                v-if="product.alreadyPosted"
                class="sv-pcard__posted"
              >{{ $t('SHOPEE_VIDEO_BULK_POSTED') }}</span>
              <span class="sv-pcard__check">
                <Icon type="md-checkmark" />
              </span>
            </div>
            <div class="sv-pcard__info">
              <span class="sv-pcard__name">{{ product.name }}</span>
              <span class="sv-pcard__price">{{ product.priceText }}</span>
            </div>
          </div>
        </div>

        <div class="sv-bulk__form">
          <div class="sv-field">
            <label class="sv-field__label">{{ $t('SHOPEE_VIDEO_CAMPAIGN') }}</label>
            <AutoComplete
              v-model="campaignName"
              transfer
              icon="ios-albums-outline"
              :placeholder="$t('SHOPEE_VIDEO_CAMPAIGN_INPUT')"
            >
              <Option
                v-for="campaign in campaignSuggestions"
                :key="campaign._id"
                :value="campaign.name"
              >
                {{ campaign.name }}
              </Option>
            </AutoComplete>
            <p class="sv-field__tip">
              {{ $t('SHOPEE_VIDEO_CAMPAIGN_TIP') }}
            </p>
          </div>
          <div class="sv-field">
            <label class="sv-field__label">{{ $t('SHOPEE_VIDEO_BULK_SUFFIX') }}</label>
            <Input
              v-model="suffix"
              :placeholder="$t('SHOPEE_VIDEO_BULK_SUFFIX_PLACEHOLDER')"
            />
            <p class="sv-field__preview">
              {{ $t('SHOPEE_VIDEO_BULK_CAPTION_PREVIEW') }}: <b>{{ captionPreview }}</b>
            </p>
          </div>
        </div>

        <div class="sv-bulk__foot">
          <Button @click="goStep(1)">
            {{ $t('SHOPEE_VIDEO_BULK_BACK') }}
          </Button>
          <Button
            type="primary"
            :disabled="!canReview"
            @click="goStep(3)"
          >
            {{ $t('SHOPEE_VIDEO_BULK_NEXT') }}
          </Button>
        </div>
      </div>

      <div
        v-show="step === 3"
        class="sv-bulk__panel"
      >
        <p class="sv-bulk__hint">
          {{ $t('SHOPEE_VIDEO_BULK_REVIEW_HINT', { max: maxPins }) }}
        </p>

        <div class="sv-review">
          <div
            v-for="product in selectedProducts"
            :key="product.itemId"
            class="sv-review__row"
          >
            <div
              class="sv-review__thumb"
              :style="thumbStyle(product)"
            >
              <video
                v-if="product.videoUrl"
                class="sv-pcard__video"
                :src="`${product.videoUrl}#t=0.5`"
                muted
                playsinline
                preload="metadata"
              />
            </div>
            <div class="sv-review__name">
              <span>{{ product.name }}</span>
              <span class="sv-review__price">{{ product.priceText }}</span>
            </div>
            <div class="sv-review__caption">
              {{ buildCaption(product.name) }}
            </div>
            <div class="sv-review__pins">
              <Tag color="primary">
                {{ product.name }}
              </Tag>
              <Tag
                v-for="pin in product.extra"
                :key="pin.itemId"
                color="primary"
                closable
                @on-close="removePin(product, pin)"
              >
                {{ pin.name }}
              </Tag>
              <Button
                v-if="product.extra.length + 1 < maxPins"
                type="dashed"
                size="small"
                icon="md-add"
                @click="openPin(product)"
              >
                {{ $t('SHOPEE_VIDEO_BULK_PIN_ADD') }}
              </Button>
            </div>
            <Button
              type="text"
              size="small"
              icon="md-close"
              class="sv-review__drop"
              @click="dropProduct(product)"
            />
          </div>
        </div>

        <div class="sv-bulk__foot">
          <Button @click="goStep(2)">
            {{ $t('SHOPEE_VIDEO_BULK_BACK') }}
          </Button>
          <span class="sv-bulk__summary">
            {{ $t('SHOPEE_VIDEO_BULK_SUMMARY', { count: selectedProducts.length, name: campaignName }) }}
          </span>
          <Button
            type="primary"
            :loading="creating"
            :disabled="!selectedProducts.length"
            @click="createBatch"
          >
            {{ $t('SHOPEE_VIDEO_BULK_CREATE') }}
          </Button>
        </div>
      </div>
    </div>

    <Modal
      v-model="pinModal.show"
      :title="$t('SHOPEE_VIDEO_BULK_PIN_TITLE')"
      footer-hide
    >
      <Input
        v-model="pinModal.query"
        search
        :placeholder="$t('SHOPEE_VIDEO_PICKER_SEARCH')"
        @on-search="searchPin"
      />
      <div class="sv-pinlist">
        <div
          v-if="pinModal.loading"
          class="sv-pinlist__state"
        >
          <Spin />
        </div>
        <p
          v-else-if="!pinModal.items.length"
          class="sv-pinlist__state"
        >
          {{ $t('SHOPEE_VIDEO_PICKER_EMPTY') }}
        </p>
        <div
          v-for="item in pinModal.items"
          v-else
          :key="item.itemId"
          class="sv-pinlist__item"
          @click="addPin(item)"
        >
          <img
            class="sv-pinlist__img"
            :src="item.coverUrl"
            @error="onImgError"
          >
          <div class="sv-pinlist__info">
            <span class="sv-pinlist__name">{{ item.name }}</span>
            <span class="sv-pinlist__price">{{ item.priceText }}</span>
          </div>
        </div>
      </div>
    </Modal>
  </div>
</template>

<script>
import { defineComponent } from '@vue/composition-api';
import PromiseMap from 'p-map';
import { getShopeeSellerInfo } from '@/api/shopee/seller/get';
import { shopeeSellerFetchProductList, getShopeeSellerProductId } from '@/api/shopee/seller/product';
import { getVideoItemList } from '@/api/shopee/seller/video';
import { videoData as getVideoData, imageUrl, videoUrl as renderVideoUrl } from '@/adapter/shopee/render/utils';
import {
  apiShopeeVideoCampaignList,
  apiShopeeVideoCampaignCreate,
  apiShopeeVideoItemList,
  apiShopeeVideoItemBulkCreate,
} from '@/api/autoshopee/shopee/shopeeVideo';
import { loggerShopee } from '@/plugins/logger';

const MAX_PINS = 6;
const SCAN_PAGE_SIZE = 48;
const SCAN_CONCURRENCY = 1;

export default defineComponent({
  data() {
    return {
      shopId: '',
      shopName: '',
      noShop: false,
      step: 1,
      scanning: false,
      scanStopped: false,
      scanned: 0,
      total: 0,
      products: [],
      postedItemIds: [],
      campaigns: [],
      campaignName: '',
      suffix: '',
      creating: false,
      maxPins: MAX_PINS,
      pinModal: {
        show: false,
        target: null,
        query: '',
        loading: false,
        items: [],
      },
    };
  },
  computed: {
    scanPercent() {
      if (!this.total) {
        return 0;
      }

      return Math.min(100, Math.round((this.scanned / this.total) * 100));
    },
    selectedProducts() {
      return this.products.filter((product) => {
        return product.checked;
      });
    },
    allSelected() {
      if (!this.products.length) {
        return false;
      }

      return this.products.every((product) => {
        return product.checked;
      });
    },
    canReview() {
      if (!this.selectedProducts.length) {
        return false;
      }

      return !!this.campaignName.trim();
    },
    captionPreview() {
      const sample = this.products[0] ? this.products[0].name : this.$t('SHOPEE_VIDEO_BULK_SAMPLE_NAME');
      return this.buildCaption(sample);
    },
    campaignSuggestions() {
      const keyword = this.campaignName.trim().toLowerCase();

      if (!keyword) {
        return this.campaigns;
      }

      return this.campaigns.filter((campaign) => {
        return `${campaign.name}`.toLowerCase().indexOf(keyword) >= 0;
      });
    },
  },
  async created() {
    await this.init();
  },
  methods: {
    async init() {
      const sellerInfo = await getShopeeSellerInfo();

      if (sellerInfo && sellerInfo.shop_id) {
        this.shopId = `${sellerInfo.shop_id}`;
        this.shopName = sellerInfo.name || '';
      }

      if (!this.shopId) {
        this.noShop = true;
        return;
      }

      await this.loadCampaigns();
      await this.loadPostedItemIds();
    },
    async loadCampaigns() {
      const list = await apiShopeeVideoCampaignList(this.shopId);
      this.campaigns = Array.isArray(list) ? list : [];
    },
    async loadPostedItemIds() {
      if (!this.campaigns.length) {
        return;
      }

      const collected = [];

      await PromiseMap(
        this.campaigns,
        async (campaign) => {
          const items = await apiShopeeVideoItemList(campaign._id);

          items.forEach((item) => {
            (item.products || []).forEach((product) => {
              collected.push(`${product.itemId}`);
            });
          });
        },
        { concurrency: 4 },
      );

      this.postedItemIds = collected;
    },
    async collectAllProducts() {
      const raw = [];
      let page = 1;
      let cursor = '';
      let total = 0;

      for (let i = 0; i < 200; i += 1) {
        if (this.scanStopped) {
          break;
        }

        const result = await shopeeSellerFetchProductList(page, SCAN_PAGE_SIZE, cursor);

        if (!result.listProduct.length) {
          break;
        }

        raw.push(...result.listProduct);
        total = result.total;
        cursor = result.cursor;
        page += SCAN_PAGE_SIZE;

        if (page > total) {
          break;
        }
      }

      return this.dedupeById(raw);
    },
    dedupeById(list) {
      const seen = {};
      const unique = [];

      list.forEach((product) => {
        const id = `${product.id}`;

        if (seen[id]) {
          return;
        }

        seen[id] = true;
        unique.push(product);
      });

      return unique;
    },
    async startScan() {
      this.scanning = true;
      this.scanStopped = false;
      this.scanned = 0;
      this.products = [];

      const raw = await this.collectAllProducts();
      this.total = raw.length;

      const found = [];

      await PromiseMap(
        raw,
        async (item) => {
          if (this.scanStopped) {
            return;
          }

          const entry = await this.resolveProductVideo(item);
          this.scanned += 1;

          if (entry) {
            found.push(entry);
            this.products = found.slice();
          }
        },
        { concurrency: SCAN_CONCURRENCY },
      );

      this.products = found;
      this.scanned = this.total;
      this.scanning = false;
    },
    stopScan() {
      this.scanStopped = true;
    },
    async resolveProductVideo(item) {
      try {
        const detail = await getShopeeSellerProductId(item.id, false);

        if (!detail) {
          return null;
        }

        const url = this.extractProductVideoUrl(detail);

        if (!url) {
          return null;
        }

        const snapshot = this.buildSnapshot(detail);
        const itemId = `${item.id}`;

        return {
          itemId,
          name: detail.name || '',
          cover: detail.cover_image || '',
          coverUrl: imageUrl(detail.cover_image || ''),
          priceText: this.formatPrice(snapshot.minPrice, snapshot.maxPrice),
          videoUrl: url,
          snapshot,
          alreadyPosted: this.postedItemIds.indexOf(itemId) >= 0,
          checked: false,
          extra: [],
        };
      } catch (error) {
        loggerShopee.error({
          msg: 'SHOPEE_VIDEO_BULK_SCAN_ERROR',
          error,
          productId: item.id,
        });

        return null;
      }
    },
    extractProductVideoUrl(detail) {
      const sellerList = detail.video_list || [];

      if (sellerList.length) {
        const first = sellerList[0];

        if (first.video_id) {
          return renderVideoUrl(first.video_id);
        }
      }

      const buyer = getVideoData(detail.video_info_list);
      return this.pickVideoUrl(buyer);
    },
    pickVideoUrl(video) {
      if (video.urlDefault) {
        return video.urlDefault;
      }

      if (video.listUrl && video.listUrl.length) {
        return video.listUrl[0];
      }

      if (video.urlRaw) {
        return video.urlRaw;
      }

      return '';
    },
    buildSnapshot(detail) {
      const modelList = detail.model_list || [];
      const prices = [];
      let stock = 0;

      modelList.forEach((model) => {
        const price = Number((model.price_info || {}).input_normal_price) || 0;

        if (price > 0) {
          prices.push(price);
        }

        if (model.stock_detail) {
          stock += model.stock_detail.total_available_stock || 0;
        }
      });

      let minPrice = 0;
      let maxPrice = 0;

      if (prices.length) {
        minPrice = Math.min(...prices);
        maxPrice = Math.max(...prices);
      }

      return {
        minPrice,
        maxPrice,
        stock,
        status: detail.status || 1,
      };
    },
    formatPrice(minPrice, maxPrice) {
      if (!minPrice) {
        return '';
      }

      const min = Math.round(minPrice);
      const max = Math.round(maxPrice);

      if (max && max !== min) {
        return `${min.toLocaleString('vi-VN')}đ - ${max.toLocaleString('vi-VN')}đ`;
      }

      return `${min.toLocaleString('vi-VN')}đ`;
    },
    thumbStyle(product) {
      if (product.coverUrl) {
        return { backgroundImage: `url(${product.coverUrl})` };
      }

      return {};
    },
    buildCaption(name) {
      const suffix = this.suffix.trim();

      if (suffix) {
        return `${name} | ${suffix}`;
      }

      return name;
    },
    goStep(step) {
      this.step = step;
    },
    toggleSelect(product) {
      product.checked = !product.checked;
    },
    toggleSelectAll() {
      const next = !this.allSelected;

      this.products.forEach((product) => {
        product.checked = next;
      });
    },
    dropProduct(product) {
      product.checked = false;
    },
    openPin(product) {
      this.pinModal.target = product;
      this.pinModal.query = '';
      this.pinModal.items = [];
      this.pinModal.show = true;
      this.searchPin();
    },
    async searchPin() {
      this.pinModal.loading = true;

      try {
        const result = await getVideoItemList(1, 20, this.pinModal.query || '');

        this.pinModal.items = (result.items || []).map((item) => {
          const snapshot = {
            minPrice: item.minPrice || 0,
            maxPrice: item.maxPrice || 0,
            stock: item.stock || 0,
            status: item.status || 1,
          };

          return {
            itemId: `${item.itemId}`,
            name: item.name || '',
            cover: item.cover || '',
            coverUrl: imageUrl(item.cover || ''),
            priceText: this.formatPrice(snapshot.minPrice, snapshot.maxPrice),
            snapshot,
          };
        });
      } catch (error) {
        loggerShopee.error({
          msg: 'SHOPEE_VIDEO_BULK_PIN_SEARCH_ERROR',
          error,
        });
        this.pinModal.items = [];
      }

      this.pinModal.loading = false;
    },
    addPin(item) {
      const product = this.pinModal.target;

      if (!product) {
        return;
      }

      if (product.extra.length + 1 >= MAX_PINS) {
        this.$Message.warning(this.$t('SHOPEE_VIDEO_PICKER_MAX', { max: MAX_PINS }));
        return;
      }

      if (item.itemId === product.itemId) {
        return;
      }

      const exists = product.extra.some((pin) => {
        return pin.itemId === item.itemId;
      });

      if (exists) {
        return;
      }

      product.extra.push({
        itemId: item.itemId,
        name: item.name,
        cover: item.cover,
        snapshot: item.snapshot,
      });

      this.pinModal.show = false;
    },
    removePin(product, pin) {
      product.extra = product.extra.filter((row) => {
        return row.itemId !== pin.itemId;
      });
    },
    onImgError(event) {
      event.target.style.visibility = 'hidden';
    },
    goDashboard() {
      this.$router.push({ name: 'ShopeeVideoDashboard' });
    },
    async resolveCampaignId() {
      const name = this.campaignName.trim();

      if (!name) {
        return '';
      }

      const existing = this.campaigns.find((campaign) => {
        return `${campaign.name}`.trim().toLowerCase() === name.toLowerCase();
      });

      if (existing && existing._id) {
        return existing._id;
      }

      const created = await apiShopeeVideoCampaignCreate({
        name,
        shopId: this.shopId,
        shopName: this.shopName,
      });

      if (created && created._id) {
        this.campaigns = [created].concat(this.campaigns);
        return created._id;
      }

      return '';
    },
    buildItemProducts(product) {
      const self = {
        itemId: product.itemId,
        name: product.name,
        cover: product.cover,
        snapshot: product.snapshot,
      };

      return [self].concat(product.extra.map((pin) => {
        return {
          itemId: pin.itemId,
          name: pin.name,
          cover: pin.cover,
          snapshot: pin.snapshot,
        };
      }));
    },
    async createBatch() {
      if (this.creating) {
        return;
      }

      this.creating = true;

      const campaignId = await this.resolveCampaignId();

      if (!campaignId) {
        this.$Message.error(this.$t('SHOPEE_VIDEO_CAMPAIGN_CREATE_ERROR'));
        this.creating = false;
        return;
      }

      const items = this.selectedProducts.map((product) => {
        return {
          source: 'shopee',
          sourceUrl: product.videoUrl,
          caption: this.buildCaption(product.name),
          products: this.buildItemProducts(product),
          status: 'draft',
        };
      });

      const created = await apiShopeeVideoItemBulkCreate(campaignId, items);

      this.creating = false;

      if (!(created && created.length)) {
        this.$Message.error(this.$t('SHOPEE_VIDEO_BULK_CREATE_ERROR'));
        return;
      }

      this.$Message.success(this.$t('SHOPEE_VIDEO_BULK_CREATE_SUCCESS', { count: created.length }));
      this.$router.push({ name: 'ShopeeVideoDashboard', query: { campaignId } });
    },
  },
});
</script>

<style lang="scss" scoped>
.sv-bulk {
  padding: 16px;

  &__card {
    background: #fff;
    border-radius: 14px;
    box-shadow: 0 4px 16px rgba(17, 24, 39, 0.06);
    padding: 24px;
    max-width: 1040px;
    margin: 0 auto;
  }

  &__head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 18px;
  }

  &__title {
    font-size: 20px;
    font-weight: 700;
    color: #1f2329;
    margin: 0;
  }

  &__desc {
    font-size: 13px;
    color: #8a8f99;
    margin: 4px 0 0;
  }

  &__steps {
    margin-bottom: 24px;
  }

  &__panel {
    min-height: 240px;
  }

  &__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 24px;
    padding-top: 16px;
    border-top: 1px solid #eef0f3;
  }

  &__summary {
    font-size: 13px;
    color: #8a8f99;
  }

  &__selbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin-bottom: 12px;
  }

  &__count {
    font-size: 13px;
    color: #515a6e;
  }

  &__form {
    display: flex;
    gap: 16px;
    margin-top: 20px;
    flex-wrap: wrap;
  }

  &__hint {
    font-size: 13px;
    color: #8a8f99;
    margin: 0 0 14px;
  }

  &__empty {
    text-align: center;
    padding: 80px 0;
    color: #b0b4bb;

    i {
      font-size: 42px;
    }

    p {
      margin-top: 10px;
      font-size: 14px;
    }
  }
}

.sv-scan {
  text-align: center;
  padding: 40px 0;

  &__stat {
    font-size: 14px;
    color: #515a6e;
  }

  &__found {
    color: #19be6b;
    font-weight: 600;
  }

  &__bar {
    height: 8px;
    background: #eceef2;
    border-radius: 99px;
    overflow: hidden;
    max-width: 460px;
    margin: 16px auto;

    i {
      display: block;
      height: 100%;
      width: 0;
      background: #ee4d2d;
      transition: width 0.25s ease;
    }
  }

  &__done {
    color: #19be6b;
    font-size: 13px;
    margin: 8px 0 0;
  }
}

.sv-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(168px, 1fr));
  gap: 12px;
  max-height: 420px;
  overflow-y: auto;
}

.sv-pcard {
  border: 1px solid #eef0f3;
  border-radius: 12px;
  overflow: hidden;
  cursor: pointer;
  background: #fff;
  transition: border-color 0.15s ease, box-shadow 0.15s ease;

  &:hover {
    border-color: #e0e3e8;
    box-shadow: 0 6px 18px rgba(17, 24, 39, 0.08);
  }

  &.is-selected {
    border-color: #2d8cf0;
    box-shadow: 0 0 0 2px rgba(45, 140, 240, 0.18);
  }

  &__thumb {
    position: relative;
    aspect-ratio: 3 / 4;
    background: #1f2329;
    background-size: cover;
    background-position: center;
  }

  &__video {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    pointer-events: none;
  }

  &__vbadge {
    position: absolute;
    top: 6px;
    left: 6px;
    font-size: 10px;
    font-weight: 700;
    color: #fff;
    background: rgba(45, 140, 240, 0.92);
    padding: 2px 7px;
    border-radius: 5px;
  }

  &__posted {
    position: absolute;
    top: 6px;
    right: 6px;
    font-size: 10px;
    font-weight: 700;
    color: #fff;
    background: rgba(31, 35, 41, 0.78);
    padding: 2px 7px;
    border-radius: 5px;
  }

  &__check {
    position: absolute;
    bottom: 6px;
    right: 6px;
    width: 22px;
    height: 22px;
    border-radius: 50%;
    background: #fff;
    border: 2px solid #cfd4da;
    display: grid;
    place-items: center;
    color: #fff;
    font-size: 13px;
  }

  &.is-selected &__check {
    background: #2d8cf0;
    border-color: #2d8cf0;
  }

  &__info {
    padding: 8px 9px;
  }

  &__name {
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
    font-size: 12.5px;
    line-height: 1.35;
    min-height: 34px;
    color: #2d2f33;
  }

  &__price {
    display: block;
    font-size: 12.5px;
    color: #ee4d2d;
    font-weight: 700;
    margin-top: 3px;
  }
}

.sv-field {
  flex: 1;
  min-width: 240px;

  &__label {
    display: block;
    font-size: 12.5px;
    font-weight: 600;
    color: #4b5059;
    margin-bottom: 6px;
  }

  &__tip {
    font-size: 12px;
    color: #b0b4bb;
    margin: 6px 0 0;
  }

  &__preview {
    margin-top: 6px;
    font-size: 12.5px;
    color: #2d2f33;
    background: #fbfbfc;
    border: 1px dashed #eef0f3;
    border-radius: 8px;
    padding: 8px 10px;

    b {
      color: #ee4d2d;
    }
  }
}

.sv-review {
  display: flex;
  flex-direction: column;
  gap: 10px;
  max-height: 460px;
  overflow-y: auto;

  &__row {
    display: flex;
    flex-shrink: 0;
    align-items: center;
    gap: 12px;
    border: 1px solid #eef0f3;
    border-radius: 12px;
    padding: 10px 12px;
  }

  &__thumb {
    position: relative;
    width: 46px;
    height: 60px;
    border-radius: 7px;
    background: #1f2329;
    background-size: cover;
    background-position: center;
    overflow: hidden;
    flex-shrink: 0;
  }

  &__name {
    width: 180px;
    flex-shrink: 0;
    font-size: 13px;
    color: #2d2f33;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }

  &__price {
    display: block;
    font-size: 12px;
    color: #ee4d2d;
    font-weight: 600;
  }

  &__caption {
    flex: 1;
    min-width: 0;
    font-size: 12.5px;
    color: #515a6e;
  }

  &__pins {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    width: 240px;
    flex-shrink: 0;
  }

  &__drop {
    flex-shrink: 0;
    color: #b0b4bb;
  }
}

.sv-pinlist {
  max-height: 320px;
  overflow-y: auto;
  margin-top: 12px;

  &__state {
    text-align: center;
    padding: 24px 0;
    color: #b0b4bb;
    font-size: 13px;
  }

  &__item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 8px;
    border-radius: 8px;
    cursor: pointer;

    &:hover {
      background: #f7f8fa;
    }
  }

  &__img {
    width: 44px;
    height: 44px;
    border-radius: 8px;
    object-fit: cover;
    flex-shrink: 0;
    background: #eef0f3;
  }

  &__info {
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 2px;
  }

  &__name {
    font-size: 13px;
    color: #2d2f33;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  &__price {
    font-size: 12px;
    color: #ee4d2d;
    font-weight: 600;
  }
}

@media (max-width: 860px) {
  .sv-bulk__form {
    flex-direction: column;
  }

  .sv-review__row {
    flex-wrap: wrap;
  }

  .sv-review__caption,
  .sv-review__pins {
    width: 100%;
  }
}
</style>
