import { format } from "quasar";
// 以下数字的方法区间均包含最大最小值。
/**
 * 随机获得一个大于等于 min 小于等于 max的整数
 * @param {Number} min
 * @param {Number} max
 * @returns {Number}
 */
function randomInt(min, max) {
  return Math.floor(Math.random() * (max + 1 - min)) + min;
}

/**
 * 生成包含max,min区间的的整数数组
 * @param {Number} min
 * @param {Number} max
 * @returns {[String]}
 */
export function generateNumberArray(min, max, pad) {
  return Array.from({ length: max + 1 - min }, (item, i) => {
    return pad ? format.pad(min + i, 2) : min + i;
  });
}

/**
 * 随机从大于等于min,小于等于max中，获得length个不同的数值
 * 如果只随机生成一个，则返回一个数值字符串，如果多个则返回数组[string]
 * @param {Number} min
 * @param {Number} max
 * @param {Number} length
 * @returns {[String]|String}
 */
function randomNumbers(min, max, length = 1) {
  let arr = generateNumberArray(min, max);
  return randomNumbersFromArray(arr, length);
}
function randomNumbersFromArray(arr, length) {
  let ret = [];
  while (length > 0) {
    let idx = randomInt(0, arr.length - 1);
    ret.push(arr[idx]);
    arr.splice(idx, 1);
    --length;
  }
  return ret;
}
function arr2Map(arr) {
  return arr.reduce((total, item) => {
    total[item] = item+'';
    return total;
  }, {});
}


function formatCartOdd({play_odd,...data}){
  data.play_odd = play_odd instanceof Array ? [] : {}
  for (let p in play_odd) {
    data.play_odd[p] = Object.keys(play_odd[p])
  }
  if(data.play_type == 'danshi' && data.play_odd instanceof Array && data.play_odd.find(item=>item.length>1)) {
    data.play_type = 'fushi'
  }
  return data
}

export const NumberLottery = {
  dlt: {
    name: "大乐透",
    defaultPlayType: "danshi",
    playTypes: [
      { name: "单式", play_type: "danshi" },
      { play_type: "dantuo", name: "胆拖" }
    ],
    fushi: {
      name: "复式",
      DEFAULT_ODD() {
        return {
          qian: {},
          hou: {}
        };
      },
      formatCartOdd(odd){
        return NumberLottery.dlt.danshi.formatCartOdd(odd)
      }
    },
    danshi: {
      name: "单式",
      DEFAULT_ODD() {
        return {
          qian: {},
          hou: {}
        };
      },
      autoSelectBet() {
        return {
          qian: arr2Map(
            randomNumbersFromArray(generateNumberArray(1, 35, 2), 5)
          ),
          hou: arr2Map(randomNumbersFromArray(generateNumberArray(1, 12, 2), 2))
        };
      },
      betsLength({ qian = {}, hou = {} }) {
        return (
          computeCombiCount(Object.keys(qian).length, 5) *
          computeCombiCount(Object.keys(hou).length, 2)
        );
      },
      validOdd(oddObj) {
        return "";
      },
      formatCartOdd(odd){
        let data = formatCartOdd(odd)
        if (data.play_odd.qian.length > 5 || data.play_odd.hou.length > 2) {
          data.play_type = 'fushi'
        }
        return data
      }
    },
    dantuo: {
      name: "胆拖",
      DEFAULT_ODD() {
        return {
          qian_dan: {},
          qian_tuo: {},
          hou_dan: {},
          hou_tuo: {}
        };
      },
      betsLength({ qian_dan, qian_tuo, hou_dan, hou_tuo }) {
        return (
          computeCombiCount(
            Object.keys(qian_tuo).length,
            5 - Object.keys(qian_dan).length
          ) *
          computeCombiCount(
            Object.keys(hou_tuo).length,
            2 - Object.keys(hou_dan).length
          )
        );
      },
      validOdd({ qian_dan, qian_tuo, hou_dan, hou_tuo }) {
        let msg = "";
        if (Object.keys(qian_dan).length + Object.keys(qian_tuo).length < 6) {
          msg = "胆拖投注至少选择6个红球";
        } else if (Object.keys(hou_tuo).length < 2) {
          msg = "后区拖码最少选择两个";
        }
        return msg;
      },
      formatCartOdd:formatCartOdd
      // autoSelectBet(){

      // },
    }
  },
  qxc: {
    name: "七星彩",
    defaultPlayType: "danshi",
    danshi: {
      name: "单式",
      DEFAULT_ODD() {
        return [{}, {}, {}, {}, {}, {}, {}];
      },
      autoSelectBet() {
        return [
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 14, 1))
        ];
      },
      betsLength(arr) {
        return ZxDsbetsLength(arr, 7);
      },
      validOdd(odd) {
        for (let p of odd) {
          if (Object.keys(p).length < 1) {
            return "每位至少选择一个号码";
          }
        }
        return "";
      },
      formatCartOdd:formatCartOdd
    },
    fushi: {
      name: "复式",
      formatCartOdd:formatCartOdd
    }
  },
  pls: {
    name: "排列三",
    defaultPlayType: "zhixuan_danshi",
    playTypes: [
      {
        group: "zhixuan",
        name: "直选",
        childs: [
          { play_type: "zhixuan_danshi", name: "直选单式" },
          { play_type: "zhixuan_fushi", name: "直选复式" },
          { play_type: "zhixuan_hezhi", name: "直选和值" }
        ]
      },
      {
        group: "zuxuan",
        name: "组选",
        childs: [
          { play_type: "zuxuan3", name: "组选3" },
          { play_type: "zuxuan6", name: "组选6" },
          { play_type: "zuxuan_hezhi", name: "组选和值" }
        ]
      }
    ],
    zhixuan_danshi: {
      name: "直选单式",
      groupIdx: 0,
      DEFAULT_ODD() {
        return [{},{},{}]
      },
      autoSelectBet() {
        return [
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1))
        ];
      },
      betsLength(oddArr) {
        return ZxDsbetsLength(oddArr, 3);
      },
      validOdd(oddArr) {
        return "";
      },
      formatCartOdd:formatCartOdd
    },
    zhixuan_fushi: {
      play_type: 'zhixuan_fushi',
      name: "直选复式",
      groupIdx: 0,
      DEFAULT_ODD() {
        return {}
      },
      autoSelectBet() {
        return arr2Map(randomNumbers(0, 9, 3));
      },
      betsLength(oddObj) {
        let arr = Object.keys(oddObj)
        return 6 * computeCombiCount(arr.length,3)
      },
      validOdd(oddObj) {
        return "";
      },
      formatCartOdd({play_odd,play_type}){
        return {play_type: play_type, play_odd: Object.keys(play_odd),bets_length:this.betsLength(play_odd)}
      }
    },
    zhixuan_hezhi: {
      name: "直选和值",
      groupIdx: 0,
      DEFAULT_ODD() {
        return {}
      },
      autoSelectBet() {
        return arr2Map(randomNumbers(0, 27, 1));
      },
      betsLength(oddObj) {
        let arr = Object.keys(oddObj)
        return arr.reduce((total,item)=>{
          let c = 0
          for(let i=0,l=Math.min(item,9);i<=l;i++){
            for(let j=0,jl=Math.min(item-i,9);j<=jl;j++){
              if(item-i-j>=0 && item-i-j<=9){
                c++
              }
            }
            // c += Math.min(item-i,9)+1
          }
          total += c
          return total
        },0)
      },
      validOdd(oddObj) {
        return "";
      },
      formatCartOdd({play_odd,play_type}){
        return {play_type: play_type, play_odd: Object.keys(play_odd),bets_length:this.betsLength(play_odd)}
      }
    },
    zuxuan3: {
      name: "组选3",
      groupIdx: 1,
      DEFAULT_ODD() {
        return {}
      },
      autoSelectBet() {
        return arr2Map(randomNumbers(0, 9, 2));
      },
      betsLength(oddObj) {
        let l = Object.keys(oddObj).length
        return l*(l-1)
      },
      validOdd(oddObj) {
        return "";
      },
      formatCartOdd({play_odd,play_type}){
        return {play_type: play_type, play_odd: Object.keys(play_odd),bets_length:this.betsLength(play_odd)}
      }
    },
    zuxuan6: {
      name: "组选6",
      groupIdx: 1,
      DEFAULT_ODD() {
        return {}
      },
      autoSelectBet() {
        return arr2Map(randomNumbers(0, 9, 3));
      },
      betsLength(oddObj) {
        let arr = Object.keys(oddObj)
        return computeCombiCount(arr.length,3)
      },
      validOdd(oddObj) {
        return "";
      },
      formatCartOdd({play_odd,play_type}){
        return {play_type: play_type, play_odd: Object.keys(play_odd),bets_length:this.betsLength(play_odd)}
      }
    },
    zuxuan_hezhi: {
      name: "组选和值",
      groupIdx: 1,
      DEFAULT_ODD() {
        return {}
      },
      autoSelectBet() {
        return arr2Map(randomNumbers(1, 26, 1));
      },
      betsLength(oddObj) {
        let arr = Object.keys(oddObj)
        return arr.reduce((total,item)=>{
          let c = 0
          for(let i=0,l=Math.floor(item/3);i<=l;i++){
            // c += Math.floor((item-i)/2)-i+1
            for(let j=i,jl=Math.min(Math.floor((item-i)/2),9);j<=jl;j++){
              if(item-i-j>=0 && item-i-j<=9 && !(i==j && item-i-j==i)){
                c++
              }
            }
          }
          total += c
          return total
        },0)
      },
      validOdd(oddObj) {
        return "";
      },
      formatCartOdd({play_odd,play_type}){
        return {play_type: play_type, play_odd: Object.keys(play_odd),bets_length:this.betsLength(play_odd)}
      }
    }
    // zhfs: {
    //   name: "组合复式",
    //   autoSelectBet() {
    //     return randomNumbers(0, 9, 3);
    //   },
    //   betsLength(arr) {
    //     if (arr.length < 3) {
    //       return 0;
    //     }
    //     return arr.reduce((total, item, i) => {
    //       return total * (i + 1);
    //     }, 1);
    //   }
    // },
    // hz: {
    //   name: "和值",
    //   autoSelectBet() {
    //     return randomNumbers(0, 27, 1);
    //   },
    //   betsLength() {}
    // },
    // zhdt: {
    //   name: "组合胆拖",
    //   autoSelectBet() {
    //     let arr = randomNumbers(0, 9, 4);
    //     return {
    //       red: arr.splice(0, 2),
    //       blue: arr
    //     };
    //   }
    // },
    // kdfs: {
    //   name: "跨度复式",
    //   autoSelectBet() {
    //     return randomNumbers(0, 9, 1);
    //   }
    //   // }
    // },
    // z3: {
    //   name: "组三",
    //   defaultPlayType: "danshi",
    //   playTypes: ["danshi", "fushi", "dantuo", "kdfs"],
    //   danshi: {
    //     name: "单式",
    //     autoSelectBet() {
    //       let arr = randomNumbers(0, 9, 2);
    //       return {
    //         multi: arr[0].repeat(2),
    //         single: arr[1]
    //       };
    //     }
    //   },
    //   fushi: {
    //     name: "复式",
    //     autoSelectBet(length = 2) {
    //       return randomNumbers(0, 9, length);
    //     }
    //   },
    //   dantuo: {
    //     name: "胆拖",
    //     autoSelectBet() {
    //       let arr = randomNumbers(0, 9, 3);
    //       return {
    //         red: arr.pop(),
    //         blue: arr
    //       };
    //     }
    //   },
    //   kdfs: {
    //     name: "跨度复式",
    //     autoSelectBet() {
    //       return randomNumbers(1, 9, 1);
    //     }
    //   }
    // },
    // z6: {
    //   name: "组六",
    //   defaultPlayType: "fushi",
    //   playTypes: ["fushi", "dantuo", "kdfs"],
    //   fushi: {
    //     name: "复式",
    //     autoSelectBet(length = 3) {
    //       return randomNumbers(0, 9, length);
    //     }
    //   },
    //   dantuo: {
    //     name: "胆拖",
    //     autoSelectBet() {
    //       let arr = randomNumbers(0, 9, 4);
    //       return {
    //         red: arr.splice(0, 2),
    //         blue: arr
    //       };
    //     }
    //   },
    //   kdfs: {
    //     name: "跨度复式",
    //     autoSelectBet() {
    //       return randomNumbers(2, 9, 1);
    //     }
    //   }
    // },
    // zxu: {
    //   name: "组选",
    //   defaultPlayType: "hz",
    //   playTypes: ["hz", "2mqb"],
    //   hz: {
    //     name: "和值",
    //     autoSelectBet() {
    //       return randomNumbers(1, 26, 1);
    //     }
    //   },
    //   "2mqb": {
    //     name: "2码全包",
    //     autoSelectBet() {
    //       return randomNumbers(0, 9, 2);
    //     }
    //   }
    // }
  },
  plw: {
    name: "排列5",
    defaultPlayType: "danshi",
    // playTypes: ["danshi", "fushi"],
    danshi: {
      name: "单式",
      // defaultPlayType: "bz",
      // playTypes: ["bz"],
      // bz: {
      //   name: "标准",
      DEFAULT_ODD() {
        return [{}, {}, {}, {}, {}];
      },
      autoSelectBet() {
        return [
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1)),
          arr2Map(randomNumbers(0, 9, 1))
        ];
      },
      betsLength(arr) {
        return ZxDsbetsLength(arr, 5);
      },
      validOdd(odd) {
        for (let p of odd) {
          if (Object.keys(p).length < 1) {
            return "每位至少选择一个号码";
          }
        }
        return "";
      },
      formatCartOdd:formatCartOdd
      // }
    },
    fushi: {
      name: "复式",
      formatCartOdd:formatCartOdd
      // defaultPlayType: "dif5",
      // playTypes: ["dif5", "same2", "same3", "g2same2", "same4", "same3same2"],
      // dif5: {
      //   name: "五不同",
      //   autoSelectBet() {
      //     return randomNumbers(0, 9, 5);
      //   }
      // },
      // same2: {
      //   name: "二同",
      //   autoSelectBet() {
      //     let arr = randomNumbers(0, 9, 4);
      //     arr.unshift(arr[0]);
      //     return arr;
      //   }
      // },
      // same3: {
      //   name: "三同",
      //   autoSelectBet() {
      //     let arr = randomNumbers(0, 9, 3);
      //     arr.unshift(arr[0], arr[0]);
      //     return arr;
      //   }
      // },
      // g2same2: {
      //   name: "两组二同",
      //   autoSelectBet() {
      //     let arr = randomNumbers(0, 9, 3);
      //     arr.unshift(arr[0]);
      //     arr.splice(2, 0, arr[2]);
      //     return arr;
      //   }
      // },
      // same4: {
      //   name: "四同",
      //   autoSelectBet() {
      //     let arr = randomNumbers(0, 9, 2);
      //     arr.unshift(arr[0], arr[0], arr[0]);
      //     return arr;
      //   }
      // },
      // same3same2: {
      //   name: "三同二同",
      //   autoSelectBet() {
      //     let arr = randomNumbers(0, 9, 2);
      //     arr.push(arr[1]);
      //     arr.unshift(arr[0], arr[0]);
      //     return arr;
      //   }
      // }
    }
  }
};


export function randomSelectBet(lotteryType, playType, params) {
  let opt = NumberLottery[lotteryType];
  let data = {
    // lotteryTypeName: opt.name,
    // lotteryType,
    play_type: playType
  };
  if (opt[playType]?.autoSelectBet) {
    opt = opt[playType];
  } else {
    data.play_type = opt.defaultPlayType;
    opt = opt[opt.defaultPlayType];
  }
  // data.playTypeName = opt.name
  
  data.play_odd = opt.autoSelectBet.call(opt, params);
  data.bets_length = opt.betsLength(data.play_odd)
  return data;
}

export const NUMBER_ZN = [
  "零",
  "一",
  "二",
  "三",
  "四",
  "五",
  "六",
  "七",
  "八",
  "九",
  "十"
];

// 无序组合数，从total个数中选出minlen个数字，有多少个组合，无序
function computeCombiCount(total, select) {
  if (select > total || select <= 0 || total <= 0) {
    return 0;
  }
  if (select == total) {
    return 1;
  }
  if (select == 1) {
    return total;
  }
  let n = 0;
  n += computeCombiCount(total - 1, select - 1); //选
  n += computeCombiCount(total - 1, select); // 不选
  return n;
}

// 直选单式，按位 长度相乘,
function ZxDsbetsLength(arr, minLen) {
  if (arr.length < minLen) {
    return 0;
  }
  return arr.reduce((total, item) => {
    return total * Object.keys(item).length;
  }, 1);
}

// 一组数字，有序排列组合，返回组合数
function orderlySortCombie(arr){
  return arr.reduce((total,item,i)=>{
    total *= i+1
    return total
  },1)
}