// Interencheres.js
'use strict';
const {Scraper} = require('../Scraper');
const InterencheresData = require('./InterencheresData');

class Interencheres extends Scraper {

  constructor(Url) {
    super(Url);

    this.platformData = new InterencheresData();
    
    this.platformData.getUrlInfo(Url).then((data) => {
      if(data.lotID == 0 && data.saleID == 0){
        throw new Error('Invalid URL');
      }
    });

    this._Name = 'interencheres'
    this._PAGE_MAIN = ""
    this._PAGE_LOGIN = ""

    this._USER = ""
    this._PWD = ""
    this._PATH_SESSION_FILE = ".session/session_inter.json"
    this._BROWSER_TOOL = "puppeteerBrowser"
  }

  getPictures = async ({ page, data}) => {

    const PictList = await this.platformData.getPictures(page, this.Url);
    console.log('PictList : '+PictList)
    return PictList    
  }

  getLotInfos = async ({ page, data}) => {
    
      console.log("getLotInfos "+this._Name+":  "+this.Url)
     
      // Navigate the page to a URL            
      await page.goto(this.Url);           
            
      let idLot = await this.platformData.getLotID(this.Url);
      console.log('idLot : '+idLot)
      
      // ## LotNumber

      let lotNumber = await this.platformData.getLotNumber(page);      
      console.log('lotNumber : '+lotNumber)


      // ## Estimate
      let {EstimateLow, EstimateHigh} = await this.platformData.getEstimate(page);
      console.log('EstimateLow : '+EstimateLow)

      // ## Description
      let Description = await this.platformData.getDescription(page);            
      //console.log('Description : '+Description)

      // ## Fees
      let {feesText, fees} = await this.platformData.getFees(page);

      console.log('feesText : '+feesText)
      console.log('fees : '+fees)
     
      // ################
      // ### SALE

      let {id_sale, urlSale} = await this.platformData.getSaleIdUrl(this.Url);

    console.log('SellNumber : '+id_sale)
    console.log('url : '+urlSale) 

    let LotInfos = {
      idPlatform: idLot,
      platform : this._Name,
      url: this.Url,
      title: 'Lot '+lotNumber,
      lotNumber: lotNumber,
      EstimateLow: EstimateLow,
      EstimateHigh: EstimateHigh,
      Description: Description,
      feesText: feesText,
      fees: fees,
      saleInfo: {
        idSale: id_sale,
        url: urlSale
      }
    }

    console.log('LotInfos : '+LotInfos)

    return LotInfos
  }

  getSaleInfos = async ({ page, data}) => {
    console.log("getSaleInfos "+this._Name+":  "+this.Url)
         
    // Navigate the page to a URL            
    await page.goto(this.Url);           

    let {id_sale, urlSale} = await this.platformData.getSaleIdUrl(this.Url);
    
    console.log('url : '+urlSale)
    // ## Title
    let title = await this.platformData.getSaleTitle(page);

    // ## Date
    let date = await this.platformData.getSaleDate(page);
    
    // ## Location
    let location = await this.platformData.getSaleLocation(page);

    // ## SaleHouseName
    let saleHouseName = await this.platformData.getSaleHouseName(page);
    
    // ## Status
    // ready : ready to be followed 
    // following : sale is followed by the AuctionAgent
    // askStop : sale is followed by the AuctionAgent and the user ask to stop following
    // pause : the Sale is stopped by the Auction House and ready to restart
    // end : the Sale is ended
    // endOnError : the Sale is ended on error
    // endOnRequest: end of follow asked by user

    let status = 'ready'

    let SaleInfo = {
      idPlatform: id_sale,
      platform : this._Name,
      url: urlSale,
      title: title,
      date: date,
      location: location,
      saleHouseName: saleHouseName,
      status: status
    }

    //console.log('SaleInfo : ', JSON.stringify(SaleInfo, null, 2));
    return SaleInfo
  }

  getLotList = async ({ page, data}) => {
    console.log("getLotList "+this._Name+":  "+this.Url)

    // Navigate the page to a URL            
    await page.goto(this.Url);    
    
    const LotList = await this.platformData.getLotList(page);
    console.log('LotList : '+LotList)
    return LotList
  }

  // ### Puppeteer
  // ###########################################################################

  async CheckCookieDialog(page) {    
    console.log("-- CheckCookieDialog --")
    return new Promise(async (resolve, reject) => {

      const CookieButton = await page.$('//button[contains(@class, "cpm-cookies-bar-cta-refus") and contains(text(), "Refuser")]');
      //console.log(CookieButton)
      if (CookieButton && await CookieButton.isVisible()) {
        console.log("-- Click on CookieButton --")
        await CookieButton.click();
      }

      resolve(true)
    })
  }

  Live = async (browser) => {
        
    console.log("Live "+this._Name+":  "+this.Url)
        
    const page = await browser.newPage();
    
    let CheckAskStop = null;
    let Socket = null;
    const StopLive = async (params) => {
      clearInterval(CheckAskStop);
      //Socket.off('Network.webSocketFrameReceived', listener);
      await this.JucundusEndSale('end')
      page.close()
      browser.close()
    }

    const listener = async (params) => {
      
      let payload = params.response.payloadData      
      if(payload.length>1 && payload.substring(0, 2) == '42'){
        payload = JSON.parse(payload.substring(2))
        //console.log(payload)

        const type = payload[0];
        const payloadData = payload[1];
    
        switch (type) {

            case 'startSale':
                break;
            case 'listAuctionedItems':
                break;

            case 'joinedSale':                  
                  await this.JucunduNextItem(
                    payloadData.sale_id, 
                    payloadData.timestamp, 
                    payloadData.item_id, 
                    payloadData.order_number.primary, 
                    payloadData.title, 
                    payloadData.description, 
                    payloadData.pricing.estimates.min,
                    payloadData.pricing.estimates.max,
                    payloadData
                  );
                  break;

            case 'auctionedItem':              
                await this.JucunduAuctionedItem(
                  payloadData.item_id,
                  payloadData.timestamp,                    
                  payloadData.auctioned.amount, 
                  payloadData.auctioned.sold, 
                  payloadData.auctioned.type
                );
                break;

            case 'nextItem':                
                await this.JucunduNextItem(
                  payloadData.sale_id, 
                  payloadData.timestamp, 
                  payloadData.item_id, 
                  payloadData.order_number.primary, 
                  payloadData.title, 
                  payloadData.description, 
                  payloadData.pricing.estimates.min,
                  payloadData.pricing.estimates.max,
                  payloadData
                );
                break;

            case 'bid':
                await this.JucundusBid(
                  payloadData.item_id, 
                  payloadData.timestamp,                  
                  payloadData.amount, 
                  payloadData.auctioned_type
                );
                break;

            case 'pauseSale':
                console.error('** Pause **');
                console.log(payloadData);
                // await this.JucundusEndSale()                
                // StopLive()
                break;

            case 'endSale':
                // await this.JucundusEndSale()                
                // StopLive()
                break;

            default:
                console.error('Unknown data type:', type);
                console.log(payloadData);
        }
      }
    };

    try{
      await page.goto(this.Url);
      
      Socket = await page.target().createCDPSession();
      await Socket.send('Network.enable');
      await Socket.send('Page.enable');
      Socket.on('Network.webSocketFrameReceived', listener);
      console.log('Listener set up for Network.webSocketFrameReceived event');
      
      // check if stop was asked 
      CheckAskStop = setInterval(async () => {
      this.JucundusCheckStop()
        .then(AskStop => {
          if(AskStop){
            StopLive()
          }
        })
    }, 5000); // 10000 milliseconds = 5 seconds

    }catch(e){
      console.log('Error : '+e)
      throw new Error('Error: '+e)
    }    

  }
};

module.exports = Interencheres