const sources = [
  "js/releasable-observer.js",
  "js/pcg-base.js",
  "js/pcg-dom-util.js",

  "js/helpers/rand.js",

  "js/model/store.js",
  "js/model/data.js",

  "js/model/provider.js",
  "js/model/slice/productTable.js",

  "js/model/tag.js",
  "js/model/product.js",

  "js/helpers/textFilter.js",
  "js/helpers/answer.js",

  "js/controller/quizBits/main.js",

  "js/controller/quizGenerator.js",
  "js/controller/quizBits/checkbox.js",
  "js/controller/quizBits/checkboxPhoto.js",
  "js/controller/quizBits/radio.js",
  "js/controller/quizBits/radioPhoto.js"
];
const fs = require('fs'),
  path = require('path');
var js = sources.map(a=>path.join(__dirname,'../../public',a)).map(n=>fs.readFileSync(n)+'').join('\n\n');


const data = require("../../db.js");
const body = 'const window = {}, localStorage = {getItem:()=>"{}"};'+js+'; return {quizGenerator, standardGenerator, initDataProvider, seeded: Math.random.seeded, rand}';


var ctx = new Function('',body)();

const rand = ctx.rand,
  seeded = ctx.seeded;

data.after = function(inComeData, skipInit){
  if( inComeData ){
    ctx.initDataProvider( data );
    countStdQ = Object.values(data.standardQuestions).length;
  }
};

let countStdQ;
module.exports = {
  '/api/generate/random': {
    method: 'GET',
    summary: 'Generate random quiz',
    options:{
      seed: {required: false, description: 'initialize random state. Make response determined', type: String},
      photo: {required: false, description: 'question with photo', type: Boolean},
      type: {required: false, description: '1 - products, 2 - standards', type: Number},
      nolog: {required: false, description: 'remove human readable log', type: Boolean}
    },
    fn: async function(args) {
      let seed = args.seed || Math.random().toString(36).substr(2);
      ctx.seeded.setStringSeed( seed );

      let multiple = seeded() > 24 / ( 46 + 24 ),
          photo = seeded() > 0.7,
          result;

      while(!result){
        if( ( args.type !== void 0 ? args.type === 2 : seeded() > 0.5 ) ){
          result = ctx.standardGenerator( () => rand( 1, countStdQ ) )
        }else{
          result = ctx.quizGenerator( multiple ? 'checkbox' : 'radio', args.photo !== void 0 ? args.photo : photo );
        }
      }

      console.log(`cat: ${result.categoryId}, prod: ${result.productId}, seed: ${seed}. ${result.question.substr(0,33)}`);

      if(args.nolog)
        delete result.log;

      return result;
    }
  },
  '/api/generate/random/sequence': {
    method: 'GET',
    summary: 'Generate list of random quizes',
    options:{
      count: {required: true, description: 'Count of generated questions', type: Number},
      seed: {required: false, description: 'initialize random state. Make response determined', type: String},
      photo: {required: false, description: 'question with photo', type: Boolean},
      type: {required: false, description: '1 - products, 2 - standards', type: Number},
      nolog: {required: false, description: 'remove human readable log', type: Boolean},
      stats: {required: false, description: 'aggregate stats and explain questions', type: Boolean},
      human: {required: false, description: 'aggregate stats and explain questions', type: Boolean}
    },
    fn: async function(args, req, res) {
      let seed = args.seed || Math.random().toString(36).substr(2);
      ctx.seeded.setStringSeed( seed );
      let used = {}, generated = 0;
      let last = {c:-1},
        list = [],
        globalMaxTries = args.count*500,
        globalTries = 0;
      if(args.count>100)args.count = 100;
      while(generated<args.count && globalTries < globalMaxTries){
        globalTries++;
        let cur = {
          m: seeded() > 24 / ( 46 + 24 ),
          p: seeded() > 0.7,
          c: 1
        };
        if( seeded() > 0.3 ){
        //if( last.c === 1 && seeded() > 0.5 ){
          cur = {
            c: 2
          };
          let id, tries = 0;
          /*do{
            id = rand(1, countStdQ);
            tries++;
            if(tries === 100){
              break;
            }
          }while('2.'+id in used);*/
          if(tries===100)
            continue;
          cur.id = id;
        }

        let tries = 0,
          result;
        do{
          if(cur.c === 1){
            result = ctx.quizGenerator( cur.m ? 'checkbox' : 'radio', cur.p );
          }else{
            let counter = 0, r = 2;
            do{
              r = rand( 1, countStdQ );
              let q = data.standardQuestions[ r ];
              if(q && !(q.category_id+'.'+q.qID in used))
                break;
              counter++;
            }while(counter < 100);
            result = ctx.standardGenerator(()=>r);
            if(result)
            if(!result){
              tries = 100;
              break;
            }
          }
          tries++;
          if(tries === 100)
            break;

        }while(result.categoryId === last.c || result.categoryId+'.'+result.productId in used);
        if(tries !== 100){
          cur.c = result.categoryId;

          used[result.categoryId+'.'+result.productId] = true;
          list.push(result);
          if(args.nolog)
            delete result.log;
          last = cur;
          generated++;
          result.number = generated;
        }
      }

      if(args.stats){
        res.header("Content-Type", "text/html; charset=utf-8");
        let stats = {};
        let statsImage = {};
        let statsCategory = {};
        let statsType = {};

        list.forEach(i=>{
          if(i.categoryId === void 0)
            debugger;
          let key = i.type+', '+(i.image?'image':'no image')+', '+i.categoryId;
          stats[key] = (stats[key]||0)+1;

          key = i.type+'';
          statsType[key] = (statsType[key]||0)+1;

          key = (i.image?'image':'no image');
          statsImage[key] = (statsImage[key]||0)+1;

          key = i.categoryId+'';
          statsCategory[key] = (statsCategory[key]||0)+1;


        });
        return '<HTML><head></head><body>' +
          `<h2>Generated: ${list.length}</h2>` +
          '<div>'+Object.keys(stats).map(k=>`<b>${k}</b>: <span>${stats[k]}</span>`).join('<br/>')+'</div>'+
          '<h2>Image</h2><div>'+Object.keys(statsImage).map(k=>`<b>${k}</b>: <span>${statsImage[k]}</span>`).join('<br/>')+'</div>'+
          '<h2>Category</h2><div>'+Object.keys(statsCategory).map(k=>`<b>${k}</b>: <span>${statsCategory[k]}</span>`).join('<br/>')+'</div>'+
          '<h2>Type</h2><div>'+Object.keys(statsType).map(k=>`<b>${k}</b>: <span>${statsType[k]}</span>`).join('<br/>')+'</div>'+
          '</body></HTML>'
      }
      if(args.human){
        res.header("Content-Type", "text/html; charset=utf-8");
        return '<HTML><head>'+`<style>
.hidden {
display: none
}
.how-block {
white-space: pre-wrap;
    padding: 0 16px;
    border-left: 4px solid #ff0060;
}
.seed {color: #999}
.title {font-size:26px}
*{font-family: Verdana;}
pre {font-family: monospace;}
.how {color: #ff0060;border-bottom: 1px dotted;font-size:14px;cursor: pointer}
</style><script>var toggle=function(a){a.parentNode.parentNode.querySelector('.how-block').classList.toggle('hidden')}</script>`+'</head><body><div class="seed">seed: '+seed+'</div> ' +
          list.map((result, i)=>
          `<div class="quest"><div class="title">${i+1}) ${result.question} <span class="how" onclick="toggle(this)">Как так получилось?</span></div> 
<pre>
${ result.answers.map(a=>
            ( (result.type==='checkbox'?(a.correct?'[v]':'[ ]'):(a.correct?'(o)':'( )'))+ ' '+a.text)
          ).join('\n')}

</pre>
<pre class="how-block hidden">${result.log.join('\n')}</pre>
</div>
`
          ).join('<br/><br/>')+
          '</body></HTML>'


      }
      return list;
    }
  }
};