import arrayDedupe from 'array-dedupe';
import lodash from 'lodash';
import axios from 'axios';
import fetchAdapter from '@vespaiach/axios-fetch-adapter';
import { onMessage } from 'webext-bridge/background';
import {
  EVENT_GET_SCRIPT_URL,
  EVENT_OPEN_POPUP,
  EVENT_GET_USER_INFO,
  EVENT_GET_AFFILIATE_PLATFORM,
  EVENT_GET_LOCAL_SETTING,
  EVENT_SHOPEE_SAVE_PRODUCT,
  EVENT_SHOPEE_LISTEN_FETCH,
  EVENT_SHOPEE_GET_HEADER_SHOPEE,
  EVENT_SHOPEE_GET_AFFILIATE_CHAT,
  EVENT_SHOPEE_GET_PRODUCT,
  EVENT_FETCH_API_AUTOSHOPEE,
} from '@/bridge/config/event';
import { openPopupUrl, tabOnUpdate, getTabLastest } from '@/browser/tab';
import { getUserInfo, getAffiliateUrl } from '../service/index';
import { allSetting } from '@/plugins/setting';
import { CacheShopeeProduct, CacheShopeeStock } from '@/plugins/store/cache';
import {
  RequestProductPayload, RequestSearchPayload, FetchListenerBucketShopee, ShopeeProductStock,
} from '@background/store/index';
import { renderContentChat } from '@/adapter/shopee/affiliate';
import { bridgeTabOnChange } from '@/bridge/background/content';
import { getConfigService } from '../get';
import { loggerBackground } from '@/plugins/logger';
import { KVShopeeProductStock } from '@/plugins/kv';

const autoshopeeApi = axios.create({
  adapter: fetchAdapter,
  responseType: 'json',
  timeout: 60000,
});

const listUrlBucketIgnore = [
  '/api/v1',
  '/api/v4/notification',
  'banhang.shopee.vn',
  '/api/v4/banner/',
  '/user',
  '/api/v4/cart/mini',
  '/api/v4/account',
  '/api/v4/abtest/traffic',
  '/api/v4/pages',
  '/api/v4/itemcard/set/elements',
  '/login',
];

getConfigService().then((getConfig) => {
  if (getConfig.fetchListenerLimit) {
    FetchListenerBucketShopee.setLimit(getConfig.fetchListenerLimit);
  }

  FetchListenerBucketShopee.setActive(getConfig.fetchListenerActive);
});

/**
 *
 * @param {string} url
 */
const filterFetchUrlPush = (url) => {
  if (listUrlBucketIgnore.some((item) => url.includes(item))) {
    return false;
  }

  return true;
};

/**
 *
 * @param {ShopeeProductData} productData
 * @returns
 */
const setCacheProductShopee = (productData) => {
  const keyCache = `${productData.shop_id}-${productData.item_id}`;
  const CacheProduct = new CacheShopeeProduct(keyCache);
  return CacheProduct.set(productData);
};

/**
 * @param {ShopeeProductBodyVariation} bodyJson
 * @param {ShopeeProductSelectVariation} jsonData
 * @returns {Promise<void>}
 */
const handleShopeeSelectVariation = async (bodyJson, jsonData) => {
  const productId = bodyJson.item_id || lodash.get(bodyJson, 'rsku_id.item_id', 0);
  const shopId = bodyJson.shop_id || lodash.get(bodyJson, 'rsku_id.shop_id', 0);

  if (!(productId && shopId)) {
    throw 'Shopee select variation error missing product_id or shop_id';
  }

  let modelId = lodash.get(bodyJson, 'rsku_id.model_id', 0) || lodash.get(jsonData, 'product_price.final_price_info.model_id', 0) || lodash.get(jsonData, 'ongoing_banner.deep_discount.model_id', 0);

  const modelTier = bodyJson.selected_tiers || null;

  if (!modelId && modelTier) {
    modelId = JSON.stringify(modelTier);
  }

  if (!modelId) {
    throw 'Shopee select variation error missing model_id';
  }

  const modelStock = lodash.get(jsonData, 'selected_variation.max_quantity', 0);

  if (!modelStock) {
    throw 'Shopee select variation error missing model_stock';
  }

  const storeKey = [
    productId,
    shopId,
  ].join('-');

  const CacheStock = new CacheShopeeStock(storeKey);
  const KvStock = new KVShopeeProductStock(storeKey);

  /** @type {Array<{modelId: number, stock: number}>} */
  let listStock = ShopeeProductStock.get(storeKey);

  if (!listStock) {
    const cachePayload = await CacheStock.get();

    if (cachePayload && cachePayload.length) {
      listStock = cachePayload;
      ShopeeProductStock.set(storeKey, listStock);
    }
  }

  if (!listStock) {
    const kvPayload = await KvStock.get();

    if (kvPayload && kvPayload.length) {
      listStock = kvPayload;
      ShopeeProductStock.set(storeKey, listStock);
    }
  }

  if (!listStock) {
    listStock = [];
    ShopeeProductStock.set(storeKey, listStock);
  }

  listStock.push({
    modelId,
    modelStock,
    stock: modelStock,
  });

  const payloadSet = arrayDedupe(listStock, ['modelId']);

  ShopeeProductStock.set(storeKey, payloadSet);

  await Promise.allSettled([
    CacheStock.set(payloadSet),
    KvStock.set(payloadSet),
  ]);

  return {
    productId,
    shopId,
    modelId,
    modelStock,
    payloadSet,
  };
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeShopeeListenFetch = async ({ data: request }) => {
  const { url, json } = request;

  if (filterFetchUrlPush(url)) {
    FetchListenerBucketShopee.pushData(url, json);
  }

  if (url.includes('pdp/cart_panel/select_variation_pc') || url.includes('pdp/get_pc_vsku')) {
    const body = JSON.parse(request.payload.body);

    await handleShopeeSelectVariation(body, json.data).then((result) => {
      loggerBackground.error({
        msg: 'SHOPEE_SELECT_VARIANT_SUCCESS',
        url,
        body,
        json: json.data,
        result,
      });
    }).catch((error) => {
      loggerBackground.error({
        msg: 'SHOPEE_SELECT_VARIANT_ERROR',
        url,
        body,
        json: json.data,
        error,
      });
    });
  }

  return true;
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeShopeeGetProduct = async ({ data }) => {
  const { productId, shopId } = data;
  const keyCache = `${shopId}-${productId}`;
  const CacheProduct = new CacheShopeeProduct(keyCache);
  return (await CacheProduct.get()) || null;
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeGetScriptUrl = async ({ data }) => ({
  scriptUrl: chrome.runtime.getURL(data.scriptPath),
});

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeOpenPopup = async ({ data }) => {
  openPopupUrl(data.path, data.qs);
  return true;
};

const onBridgeGetUserInfo = async () => {
  return await getUserInfo();
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeGetAffiliatePlatform = async ({ data }) => {
  return await getAffiliateUrl(data.platform);
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeGetLocalSetting = async ({ data }) => {
  return await allSetting[data.key].getSync();
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeShopeeSaveProduct = async ({ data }) => {
  setCacheProductShopee(data);
  return true;
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeShopeeGetHeaderShopee = async ({ data }) => {
  const getBy = data.by;
  if (getBy === 'product') {
    return RequestProductPayload.getList();
  }
  if (getBy === 'search') {
    return RequestSearchPayload.getList();
  }
  return [];
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns
 */
const onBridgeShopeeGetAffiliateChat = async ({ data }) => {
  try {
    const chatMessage = await renderContentChat(data);
    return chatMessage;
  } catch {
    return 'ERROR';
  }
};

/**
 *
 * @param {BridgeParamBridgeMessage} param
 * @returns {Promise<object>}
 */
const onBridgeFetchApiAutoshopee = async ({ data }) => {
  const response = await autoshopeeApi.request({
    ...data,
    data: data.body,
  });
  return response.data;
};

const SHOPEE_TAB_URL_PATTERNS = ['shopee.vn', 'banhang.shopee.vn'];

const isShopeeTab = (tabData) => {
  if (!tabData || !tabData.url) {
    return false;
  }
  return SHOPEE_TAB_URL_PATTERNS.some((pattern) => tabData.url.includes(pattern));
};

const onBridgerTabChange = async () => {
  const tabData = await getTabLastest();

  if (!(tabData && tabData.id)) {
    return 0;
  }

  if (!isShopeeTab(tabData)) {
    return 0;
  }

  bridgeTabOnChange(tabData.id, tabData).catch(() => {});

  return tabData.id;
};

const startKeepAlive = () => chrome.runtime.onConnect.addListener((port) => {
  if (port.name === 'keepAlive') {
    port.onMessage.addListener((data) => {
      if (data.ping) {
        if (false) {
          loggerBackground.log({
            msg: 'KeepAlive Connected',
            from: data.from,
          });
        }
      }
    });

    port.onDisconnect.addListener(() => {
      if (false) {
        loggerBackground.error({
          msg: 'KeepAlive Disconnected',
        });
      }
    });
  }
});

export const brideService = async () => {
  startKeepAlive();

  onMessage(EVENT_SHOPEE_LISTEN_FETCH, onBridgeShopeeListenFetch);
  onMessage(EVENT_SHOPEE_GET_PRODUCT, onBridgeShopeeGetProduct);
  onMessage(EVENT_GET_SCRIPT_URL, onBridgeGetScriptUrl);
  onMessage(EVENT_OPEN_POPUP, onBridgeOpenPopup);
  onMessage(EVENT_GET_USER_INFO, onBridgeGetUserInfo);
  onMessage(EVENT_GET_AFFILIATE_PLATFORM, onBridgeGetAffiliatePlatform);
  onMessage(EVENT_GET_LOCAL_SETTING, onBridgeGetLocalSetting);
  onMessage(EVENT_SHOPEE_SAVE_PRODUCT, onBridgeShopeeSaveProduct);
  onMessage(EVENT_SHOPEE_GET_HEADER_SHOPEE, onBridgeShopeeGetHeaderShopee);
  onMessage(EVENT_SHOPEE_GET_AFFILIATE_CHAT, onBridgeShopeeGetAffiliateChat);
  onMessage(EVENT_FETCH_API_AUTOSHOPEE, onBridgeFetchApiAutoshopee);

  tabOnUpdate(onBridgerTabChange);
};
