# Adapter Pattern

## Tổng quan

Adapter pattern trong AutoShopee Kit chịu trách nhiệm **chuyển đổi dữ liệu** giữa các nền tảng thương mại điện tử (Shopee, TikTok) về một format thống nhất. Mỗi nền tảng có cấu trúc API riêng, adapter đóng vai trò trung gian để:

- Chuẩn hóa dữ liệu sản phẩm từ API nguồn về format nội bộ
- Chuyển đổi dữ liệu nội bộ thành payload phù hợp để gọi API đích
- Hỗ trợ clone sản phẩm cross-platform (TikTok → Shopee)
- Render URL, hình ảnh, video theo từng nền tảng

```
src/app/adapter/
├── shopee/
│   ├── adapter.js          # Chuyển đổi dữ liệu chi tiết & tạo sản phẩm
│   ├── affiliate.js        # Render nội dung chat affiliate
│   ├── product.js          # Xử lý clone sản phẩm, video, mô tả
│   └── render/
│       ├── index.js         # Re-export utils + product
│       ├── utils.js         # URL builder (image, video, product, shop)
│       └── product.js       # Render chi tiết sản phẩm cho UI hiển thị
└── tiktok/
    ├── product.js           # Migrate sản phẩm TikTok → Shopee
    └── render.js            # Xây dựng URL hình ảnh TikTok
```

## Shopee Adapters

### `shopee/adapter.js`

Chuyển đổi dữ liệu sản phẩm Shopee ở 2 chiều:

**`adapterDetailProduct(raw)`** — Chuẩn hóa dữ liệu chi tiết sản phẩm từ API Shopee

- Gộp nhiều object con (`product_price`, `product_images`, `product_attributes`, `product_review`, `product_meta`, `item`) thành một object phẳng
- Map lại field name: `title` → `name`, `item_id` → `itemid`, `shop_id` → `shopid`
- Tính tổng `sold` từ tất cả model
- Map `global_sold` → `historical_sold`

**`adapterCreateProduct(payload)`** — Chuyển đổi payload nội bộ thành format API tạo sản phẩm Shopee

- Chuyển `weight` sang object `{ unit, value }`
- Wrap `description` vào `description_info` với `description_type`
- Xử lý `description_json` (rich text) thành `field_list` với type 0 (text) và type 1 (image)
- Chuyển `dimension` sang string
- Map `tier_variation` sang `std_tier_variation_list` với format Shopee
- Map `attributes` sang format `{ attribute_id, attribute_values: [{ value_id | raw_value, unit }] }`

### `shopee/product.js`

Xử lý sản phẩm Shopee cho các tính năng clone và đồng bộ.

**`priceFix(price, fixVal)` / `priceListFix(data)`** — Chia giá trị giá cho 100000 (format API Shopee lưu giá nhân hệ số)

**`refactorProduct(product, fixPrice)`** — Chuẩn hóa sản phẩm Shopee về format nội bộ

- Fix giá nếu cần
- Xử lý video từ `video_info_list`
- Sort và map models theo `tier_index`, gán image từ `tier_variations`
- Chuyển image ID sang full URL
- Tạo `productId`, `shopId`, `sku`, `url`
- Gắn `platform: 'shopee'`

**`syncVideoProduct(productData, videoAppend)`** — Gộp video list cũ và mới, loại trùng theo `video_id`

**`renderCloneProduct(dataProduct, listAttrProduct, editParam, listWarehouseId)`** — Tạo payload clone sản phẩm Shopee

Hàm phức tạp nhất, xử lý toàn bộ logic clone:

- Tính giá mới dựa trên `editParam.price.change` (hỗ trợ `%`, `$`, hoặc cộng thêm)
- Map attributes từ sản phẩm nguồn sang danh sách attribute của danh mục đích
- Xử lý `Expiry Date` attribute tự động (default 365 ngày)
- Giới hạn số model theo `configShopee.maxModelCount`
- Xử lý warehouse stock theo `listWarehouseId`
- Áp dụng `editParam`: prepend/append title, prepend/append description, spin image, replace phone
- Xử lý pre-order và days_to_ship theo config
- Giới hạn `name` và `description` theo max length config
- Hỗ trợ rich text description (`description_json`)

**`overrideDescriptionJson(descriptionJson, descriptionText)`** — Ghi đè phần text trong rich text description, giữ nguyên hình ảnh

### `shopee/affiliate.js`

**`renderContentChat({ id, name })`** — Tạo nội dung chat affiliate

- Lấy template text từ setting (`shopeeAffContent`)
- Tạo short link từ product URL
- Replace placeholder `[PRODUCT_NAME]` và `[SHORT_LINK]`

### `shopee/render/utils.js`

Các hàm tiện ích tạo URL cho Shopee:

| Hàm | Mô tả | Ví dụ output |
|-----|--------|--------------|
| `fixPrice(price)` | Loại bỏ `.00` ở cuối giá | `50000` |
| `imageId(url)` | Trích image ID từ URL | `abc123def` |
| `imageUrl(id, isZip)` | Tạo full URL từ image ID | `https://cf.shopee.vn/file/abc123` |
| `videoUrl(id)` | Tạo URL video | `https://cv.shopee.vn/file/abc` |
| `productSeller(id)` | URL sản phẩm trên Seller Center | `/portal/product/123` |
| `flashSaleSeller(id)` | URL flash sale trên Seller Center | `/portal/marketing/shop-flash-sale/123` |
| `productUrl(productId, shopId)` | URL sản phẩm trên trang mua | `/product/shopId/productId` |
| `shopUrlName(username)` | URL shop theo username | `/username` |
| `shopUrlId(shopId)` | URL shop theo ID | `/shop/shopId` |
| `searchByKeyword(keyword)` | URL tìm kiếm | `/search?keyword=abc` |
| `videoData(videoInfo)` | Parse video info thành object | `{ id, urlRaw, listUrl, urlDefault }` |

Ngoài ra export 2 constant: `sellerLoginUrl`, `buyerLoginUrl`

### `shopee/render/product.js`

**`renderProductDetail(productData)`** — Render chi tiết sản phẩm để hiển thị trên UI

Trả về object gồm:

- `metaData` — Tên, mô tả, image, video, currency, thời gian tạo, tổng bán, tổng doanh thu
- `shopData` — Thông tin shop: tên, avatar, username, location, rating, follower, thời gian online
- `listVariation` — Danh sách variation: id, name, price, promotion, stock, discount %, sold, sale
- `listImage` — Tổng hợp tất cả hình: main images, long images, description images, variation images
- `listTag` — Trích hashtag từ description

## TikTok Adapters

### `tiktok/render.js`

**`getTiktokImageUrl(imageId)`** — Tạo URL hình ảnh TikTok từ image ID

- Sử dụng CDN `p16-oec-va.ibyteimg.com`
- Size cố định `1920:1920`, format WebP

### `tiktok/product.js`

**Class `TiktokProductMirgateShopee`** — Migrate sản phẩm từ TikTok sang Shopee

Constructor nhận `TiktokPdpProductId` và khởi tạo các list rỗng: `listAttribute`, `listWarehouse`, `listCategory`, `listLogistic`, `listVideo` (được set từ bên ngoài trước khi gọi `getPayload`).

**`getPayload(payloadMigrate)`** — Tạo `ShopeePayloadProductCreate` từ dữ liệu TikTok

- Map `sale_props` → `tier_variation` (tên variation, options, images)
- Map `skus` → `model_list` (price, stock, tier_index, sku)
- Hỗ trợ `payloadMigrate.priceChange` (%, $, hoặc cộng thêm)
- Hỗ trợ `payloadMigrate.beforeDiscount` để chọn giá gốc hay giá sale
- Parse description từ `desc_detail` JSON
- Giới hạn name/description theo config Shopee
- Gán warehouse stock nếu có

**`mirgateImageUrl(imageUri)`** — Chuyển 1 hình TikTok sang Shopee

- Kiểm tra cache (`CacheTiktokImageShopee`)
- Tải hình từ URL TikTok → upload blob lên Shopee → lưu cache
- Trả về image ID Shopee

**`mirgateImageList(callbackLog)`** — Chuyển toàn bộ hình sản phẩm và variation

- Xử lý song song (concurrency: 2)
- Gọi callback log cho từng hình (hiển thị tiến trình)
- Xử lý cả product images và sale prop images

## Lazada Adapters

Hiện tại **chưa có adapter cho Lazada**. Lazada chỉ có constant URL cho chức năng in đơn hàng (`LAZADA_URLS.SELLER_PRINT_PDF`).

## Sơ đồ luồng dữ liệu

### Clone sản phẩm Shopee → Shopee

```
API Shopee (nguồn)
    │
    ▼
adapterDetailProduct()     ◄── Chuẩn hóa raw data
    │
    ▼
refactorProduct()          ◄── Fix price, map image URLs, sort models
    │
    ▼
renderCloneProduct()       ◄── Áp dụng edit params, tạo payload
    │
    ▼
adapterCreateProduct()     ◄── Chuyển sang format API Shopee
    │
    ▼
API Shopee (đích)
```

### Migrate sản phẩm TikTok → Shopee

```
API TikTok (nguồn)
    │
    ▼
TiktokProductMirgateShopee
    │
    ├── mirgateImageList()    ◄── Upload hình TikTok → Shopee (có cache)
    │       │
    │       ├── getTiktokImageUrl()    ◄── Tạo URL hình TikTok
    │       ├── getImageUrlData()      ◄── Tải blob hình
    │       └── uploadImageBloob()     ◄── Upload lên Shopee
    │
    └── getPayload()          ◄── Map dữ liệu TikTok → ShopeePayloadProductCreate
            │
            ▼
    API Shopee (đích)
```

### Render sản phẩm cho UI

```
Dữ liệu sản phẩm (đã chuẩn hóa)
    │
    ▼
renderProductDetail()      ◄── Tổng hợp metadata, shop, variations, images
    │
    ▼
Vue Component              ◄── Hiển thị chi tiết sản phẩm
```
