const port = 20114
  , express = require("express")
  , fetch = require("node-fetch")
  , cron = require('node-cron')
  , expressLogging = require('express-logging')
  , logger = require('logops')
  , db = require('./src/model');


const Coupang = {
  data: {
    url: 'http://127.0.0.1:20113',
    cache: {}
  },
  methods: {
    appendProduct: () => {

    },
    getQuery(obj) {
      var str = [];
      for (var p in obj)
        if (obj.hasOwnProperty(p)) {
          str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        }
      return str.join("&");
    },

    getDateRange: (gap = 10) => {
      let date = new Date();
      let yesterday = date - 1000 * 60 * 60 * 24 * gap;
      yesterday = new Date(yesterday);
      yesterday = [yesterday.getFullYear(),
      (yesterday.getMonth() + 1 < 10 ? '0' + (yesterday.getMonth() + 1) : yesterday.getMonth() + 1),
      (yesterday.getDate() < 10 ? '0' + (yesterday.getDate()) : yesterday.getDate())].join('-')
      date = new Date(date + 1000 * 60 * 60 * 24)
      let tomorrow = [date.getFullYear(),
      (date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1),
      (date.getDate() < 10 ? '0' + (date.getDate()) : date.getDate())].join('-')
      return { yesterday: yesterday, tomorrow: tomorrow }
    },

    getProductPage: (nextToken = 1) => {
      fetch(Coupang.data.url + '/product?' + Coupang.methods.getQuery({ nextToken: nextToken, maxPerPage: 1, vendorId: 'A00184338' }))
        .then(res => res.text()).then(body => {
          let products = JSON.parse(body);
          if (products.code == 200) {
            products.data.data.map((v, k) => {
              db.CoupangModel.findAll({ where: { productId: v.productId } }).then(row => {
                if (row.length) {
                  db.CoupangModel.update(v, { where: { productId: v.productId } }).then(row => {
                    logger.info({ productId: v.productId }, 'Updated row productId')
                  })
                } else {
                  db.CoupangModel.create(v).then(res => {
                    res.map((v, k) => {
                      logger.info({ productId: v.productId }, 'Inserted row productId')
                    })
                  }).catch(err => err.message)
                }
              })
            })
            if (products.data.nextToken) {
              logger.info({ nextToken: products.data.nextToken }, 'Next Token')
              Coupang.methods.getProductPage(products.data.nextToken);
            } else {
              logger.info({}, 'Fetching all coupang product pages successfully!');
              setTimeout(Coupang.methods.getProducts, 5000);
            }
          }
        })
    },

    getProducts: (page = 1) => {
      let limit = 30
      let sellerProductId = 0
      db.CoupangModel.findAll({ limit: limit, offset: limit * (page - 1) }).then(results => {
        if (results.length) {
          results.map((result, index) => {
            sellerProductId = result.sellerProductId
            fetch(Coupang.data.url + '/product/' + sellerProductId)
              .then(res => res.text()).then(body => {
                let product = JSON.parse(body);
                if (product.code == 200) {
                  let v = product.data.data
                  db.CoupangModel.findAll({ where: { sellerProductId: v.sellerProductId } }).then(rows => {
                    if (rows.length) {
                      db.CoupangModel.update({ sellerProductId: v.sellerProductId, productId: v.productId, detail: v.items[0].contents[0].contentDetails[0].content }, { where: { sellerProductId: v.sellerProductId } }).then(row => {
                        logger.info({ sellerProductId: v.sellerProductId }, 'Updated row by sellerProductId')
                      })
                    }
                  })
                }
              })
            if (index == (limit - 1)) {
              Coupang.methods.getProducts(++page);
            }
          })
        }
      })
    },

    getOrders: () => {
      let dateRange = Coupang.methods.getDateRange(5)
      fetch(Coupang.data.url + '/orders?' + Coupang.methods.getQuery({
        createdAtFrom: dateRange.yesterday,
        createdAtTo: dateRange.tomorrow,
        maxPerPage: 2,
        status: 'ACCEPT'
      }))
        .then(res => res.text()).then(orders => {
          orders = JSON.parse(orders);
          if (orders.code == 200 && orders.data.code == 200) {
            orders.data.data.map((v, k) => {
              db.CoupangOrderModel.findAll({ where: { orderId: v.OrderId } }).then(row => {
                if (row.length) {
                  db.CoupangModel.update(v, { where: { productId: v.productId } }).then(row => {
                    logger.info({ productId: v.productId }, 'Updated row productId')
                  })
                } else {
                  db.CoupangModel.create(v).then(res => {
                    res.map((v, k) => {
                      logger.info({ productId: v.productId }, 'Inserted row productId')
                    })
                  }).catch(err => err.message)
                }
              })
            })
          }
        })
    },

    getCategories: (nextToken = 1) => {
      fetch(Coupang.data.url + '/categories')
        .then(res => res.text()).then(body => {
          body = JSON.parse(body);
          if (body.code == 200) {
            Coupang.data.cache.categories = body.data
          }
        })
    }
  }
}

cron.schedule('0 10,30,50 * * * *', () => {
  Coupang.methods.getProductPage();
  Coupang.methods.getCategories();
  Coupang.methods.getOrders();
});

var app = express();
app.use(expressLogging(logger));
app.listen(port, () => {
  Coupang.methods.getProductPage();
  Coupang.methods.getCategories();
  Coupang.methods.getOrders();
  logger.info({ port: port }, "Server started...");
});

app.get('/categories', (req, res, next) => {
  let result = [];
  let traverse = (child, path = [], code = 0) => {
    if (child.length && code != 93185) {
      for (let c of child) {
        !path.length ? path.push('') : path.push(c.name)
        traverse(c.child, path, c.displayItemCategoryCode);
      }
    } else {
      shortenPath = path.slice(-4).join(' > ')
      result.push({ path: shortenPath, code: code });
    }
  }
  traverse(Coupang.data.cache.categories.data.child)
  res.json({ code: 200, data: result })
})


