const Logs = require('../libs/logs');
const eventsCombination = require('./trangleCalc');

const Request = {
  callbacks: {},
  count: 0,
}

// const WIN_STEP = 15;
// const SOL_FREEZ_TIME = 1000 * 30;

const GLOBAL_DATA = {
  relationLength: 0,
  solutions: {},
};

const getDataFromParent = (type, callback) => {
  const id = ++Request.count;
  Request.callbacks[id] = callback;
  process.send({ method: 'get', id, type });
}

const postDataToParent = (type, data) => {
  process.send({ method: 'post', type, data });
}

process.on('message', (message) => {
  const { callbacks } = Request;
  const { method, id, type, data } = message;
  if (method == 'get' && id) {
    let responseData = null;
    // if (data == 'getSolution') {
    //   responseData = Solution.get();
    // }
    process.send({ type: 'response', id, data: responseData });
  }
  else if (type == 'response' && id && callbacks[id]) {
    callbacks[id](data);
    delete callbacks[id];
  }
});

/**
 * 精确浮点数字
 * @param {number} number
 * @param {number} x
 * @returns {number}
 */
const fixFloat = (number, x=2) => {
  return parseFloat(number.toFixed(x));
}

const getGamesRelation = () => {
  return new Promise(resolve => {
    getDataFromParent('getGamesRelation', (relations) => {
      resolve(relations);
    });
  });
}

const getSolutionHistory = () => {
  return new Promise(resolve => {
    getDataFromParent('getSolutionHistory', (solutions) => {
      resolve(solutions);
    });
  });
}

const setSolution = (solutions) => {
  postDataToParent('setSolution', solutions);
}

const extractOdds = ({ evtime, events, sptime, special }) => {
  const expireTime = Date.now() - 15000;
  let odds = {};
  if (evtime > expireTime) {
    odds = { ...odds, ...events };
  }
  if (sptime > expireTime) {
    odds = { ...odds, ...special };
  }
  return odds;
}

// const getOptimalOdds = (oddsMap) => {
//   const oddsInfo = {};
//   Object.keys(oddsMap).forEach(platform => {
//     const odds = oddsMap[platform];
//     Object.keys(odds).forEach(ior => {
//       const oddsValue = odds[ior];
//       if (!oddsInfo[ior] || oddsInfo[ior]?.v < oddsValue) {
//         oddsInfo[ior] = {
//           p: platform,
//           v: oddsValue
//         }
//       }
//     });
//   });
//   return oddsInfo;
// }

const eventMatch = () => {
  getGamesRelation()
  .then(relations => {
    const nowTime = Date.now();
    relations = relations.filter(relaiton => {
      const expire = Object.values(relaiton.rel).find(event => event.timestamp <= nowTime);
      if (expire) {
        return false;
      }
      return true;
    });

    const relationLength = relations.length;
    if (!relationLength) {
      if (GLOBAL_DATA.relationLength) {
        GLOBAL_DATA.relationLength = 0;
        Logs.out('relation list is empty');
      }
      return [];
    }

    GLOBAL_DATA.relationLength = relationLength;

    const passableEvents = relations.map(({ id, rel }) => {
      const eventsMap = {};
      const oddsMap = {};
      Object.keys(rel).forEach(platform => {
        const { leagueName, teamHomeName, teamAwayName, timestamp, evtime, events, sptime, special } = rel[platform];
        if (!events && !special) {
          return;
        }
        if (!eventsMap.info) {
          eventsMap.info = { leagueName, teamHomeName, teamAwayName, id, timestamp };
        }
        const odds = extractOdds({ evtime, events, sptime, special });
        Object.keys(odds).forEach(ior => {
          if (!oddsMap[ior]) {
            oddsMap[ior] = {};
          }
          oddsMap[ior][platform] = odds[ior];
        });
      });
      eventsMap.odds = oddsMap;
      return eventsMap;
    });

    const solutions = eventsCombination(passableEvents);
    postDataToParent('setSolutions', solutions);
  })
  .finally(() => {
    setTimeout(() => {
      eventMatch();
    }, 2000);
  });
};

eventMatch();