const datetime = require("../../config/datetime");
const Answare = require("../model/Answare.js");
const AutoQuartions = require("../model/auto/Quartions");
const AutoAnswares = require("../model/auto/Answare");
const Match = require("../model/Match");
const Quartion = require("../model/Quartion");
const Sport = require("../model/Sport");
const Controller = require("./Controller");
const reponceTitle = require("../helpers/replaceTitle");
const Betting = require("../model/Betting");
const { AppEvent, AppEventType } = require("../event/my.event.js");
module.exports = new class MatchController extends Controller {
   call = () => {
      AppEvent.emit(AppEventType.call, "");
   }
   add = async (req, res, next) => {
      try {
         const { sportId, leagueId, name1, name2, live, start, end } = req.body;
         const sport = await Sport.find(sportId);
         const user = req.user;
         const payload = {
            sport_name: sport.name,
            league_name: leagueId,
            icon: sport.icon,
            sport_id: sport.id,
            live_time: datetime.bd(live),
            start_time: datetime.bd(start),
            end_time: datetime.bd(end),
            tream_a: name1,
            tream_b: name2,
            creator_id: user.id,
            is_show: "off",
            is_lock: "on"
         }
         await Match.add(payload);

         return res.success("success");
      } catch (error) {
         return next(error.toString())
      }
   }
   index = async (req, res, next) => {
      try {
         const data = await Match.get().where("type", "!=", "closed").orderBy("start_time","asc");
         const respopnce = [];
         for (const match of data) {
            const better = await Betting.where("match_id", match.id);
            const win = better.filter(it => it.status == "win").reduce((o, d) => o += parseFloat(d.taka), 0)
            const loss= better.filter(it => it.status == "loss").reduce((o, d) => o += parseFloat(d.taka), 0)


            respopnce.push({
               ...match,
               show: match.is_show === "on",
               title: match.tream_a + " vs " + match.tream_b,
               user: better.length,
               total: better.reduce((o, d) => o += parseFloat(d.taka), 0),
               win,
               loss,
               pending: better.filter(it => it.status == "pending").reduce((o, d) => o += parseFloat(d.taka), 0),
               finaly: (loss - win).toString().replace("-","loss "),
            })
         }
         return res.success("success", respopnce);
      } catch (error) {
         return next(error.toString());
      }
   }
   closeddata = async (req, res, next) => {
      try {
         const data = await Match.get().where("type", "closed");
         const respopnce = [];
         for (const match of data) {
            respopnce.push({
               ...match,
               show: match.is_show === "on",
               title: match.tream_a + " vs " + match.tream_b,
               user: 100,
               total: 1000,
               win: 1000,
               loss: 1000,
               pending: 100,
               finaly: "-1000",
            })
         }
         return res.success("success", respopnce);
      } catch (error) {
         return next(error.toString());
      }
   }
   live = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Match.update(id, (data) => {
            if (data.type === "live") return { type: "comming" }
            if (data.type === "comming") return { type: "live" }
            return null;
         });
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   closed = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Match.update(id, ({ type }) => ({ type: type == "closed" ? "live" : "closed" }));
         return res.success("Closed successfull");
      } catch (error) {
         return next(error.toString());
      }
   }
   // set socre in game
   score = async (req, res, next) => {
      try {
         const { id } = req.params;
         const { score } = req.body;
         await Match.update(id, () => ({ score }));
         this.call();
         return res.success("Score Update successfull");
      } catch (error) {
         console.log(error.toString());
         return next(error.toString());
      }
   }
   // vet off/lock
   lock = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Match.update(id, (data) => ({ is_lock: data.is_lock === "off" ? "on" : "off" }));
         this.call();
         return res.success("lock successfull");
      } catch (error) {
         return next(error.toString());
      }
   }
   // bet hide on user panle
   show = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Match.update(id, (data) => ({ is_show: data.is_show === "off" ? "on" : "off" }));
         this.call();
         return res.success("successfull");
      } catch (error) {
         return next(error.toString());
      }
   }
   // find
   headata = async (id) => {
      const match = await Match.find(id);
      const reponce = {
         ...match,
         title: match.tream_a + " vs " + match.tream_b,
         show: match.is_show === "on",
         lock: match.is_lock === "on",
      }
      return reponce;
   }
   find = async (req, res, next) => {
      try {
         const { id } = req.params;
         return res.success("success", await this.headata(id));
      } catch (error) {
         return next(error.toString());
      }
   }
   // quariont---------------
   quartionAdd = async (req, res, next) => {
      try {
         const { id } = req.params;
         const { auto } = req.body;
         if (!auto) throw "value not found";
         const match = await Match.find(id);
         const _quartion = await AutoQuartions.find(auto);
         const payload = {
            match_id: match.id,
            title: _quartion.title,
            resuld_type: _quartion.resuld_type,
            createot_id: req.user.id,
            is_lock: "off",
            is_show: "off",
            is_add: _quartion.is_adds == "yes" ? "on" : "off",
            is_edite: "on",
            is_run_show: _quartion.is_runs == "yes" ? "on" : "off",
            is_ret_show: _quartion.is_rets == "yes" ? "on" : "off",
            is_over_show: _quartion.is_overs == "yes" ? "on" : "off",
         }
         const reulsd = await Quartion.add(payload);
         if (reulsd) {
            const _answares = await AutoAnswares.get().where("quarion_id", "=", auto);
            if (_answares.length > 0) {
               await Promise.all(
                  _answares.map((item) => Answare.add({
                     quertion_id: reulsd.id,
                     title: item.title,
                     ret: item.ret,
                     is_show: "off",
                     is_lock: "off",
                     createot_id: req.user.id
                  }))
               )
            }
         }
         this.call();
         return res.success("Add success");
      } catch (error) {
         return next(error.toString());
      }
   }
   q_data = async (id) => {
      const match = await Match.find(id);
      const reponce = [];
      const datas = await Quartion.get().where("match_id", "=", match.id);
      const allbet = await Betting.where("match_id", match.id);
      for (const data of datas) {
         const anslist = await Answare.get().where("quertion_id", "=", data.id);
         const total_better = allbet.filter(item => item.queartion_id == data.id);
         const total_bet = total_better.reduce((total, data) => total + parseFloat(data.taka), 0);
         const foundResud = total_better.filter(item => ['win', 'loss'].includes(item.status));
         const pending_bet = total_better.filter(item => ['pending'].includes(item.status));
         reponce.push({
            ...data,
            resuld: foundResud.length > 0,
            total_better: total_better.length,
            total_bet,
            pending_bet: pending_bet.length,
            title: reponceTitle(data.title, match.tream_a, match.tream_b, data.runs, data.rets, data.overs),
            list: anslist.map((item) => {
               const better = total_better.filter(itm => itm.answare_id == item.id);
               const better_amount = better.reduce((total, data) => total + parseFloat(data.taka), 0);
               return {
                  ...item,
                  better: better.length,
                  better_amount,
                  win: better.filter(({ status }) => status == "win").length > 0,
                  title: reponceTitle(item.title, match.tream_a, match.tream_b, data.runs, data.rets, data.overs),
                  ret: data.is_ret_show == "on" ? reponceTitle("(rets)", null, null, null, data.rets, null) : item.ret
               }
            })
         })
      }
      return reponce;
   }
   quartions = async (req, res, next) => {
      try {
         const { id } = req.params;
         const data = await this.q_data(id);
         return res.success("success", data);
      } catch (error) {
         return next(error.toString());
      }
   }
   runretover = async (req, res, next) => {
      try {
         const { id } = req.params;
         const { value } = req.body;
         await Quartion.update(id, (v) => (value))
         this.call();
         return res.success("success", "");
      } catch (error) {
         return next(error.toString());
      }
   }
   quartiondelete = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Quartion.del(id)
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   quartionhide = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Quartion.update(id, (value) => {
            if (value.is_show == "on") {
               return { is_show: "off" }
            } else {
               return { is_show: "on" }
            }
         });
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   quartionlock = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Quartion.update(id, (value) => {
            if (value.is_lock == "on") {
               return { is_lock: "off" }
            } else {
               return { is_lock: "on" }
            }
         });
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   quartionupdate = async (req, res, next) => {
      try {
         const { id } = req.params;
         const { value } = req.body;
         if (!value) return next("Data not found!");
         const payload = { title: value }
         await Quartion.update(id, (value) => payload);
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   // answare-----------------------------
   ansAdd = async (req, res, next) => {
      try {
         const { id } = req.params;
         const { title, ret } = req.body;
         if (!title || !ret) return next("Data not found!");

         const quartion = await Quartion.find(id);
         const payload = {
            quertion_id: quartion.id,
            title: "--",
            ret,
            is_show: "off",
            is_lock: "on",
            createot_id: req.user.id
         }
         await Answare.add(payload)
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   anslockhide = async (req, res, next) => {
      try {
         const { id, name } = req.params;
         await Answare.update(id, (value) => {
            if (value[name] == "on") {
               return { [name]: "off" }
            } else {
               return { [name]: "on" }
            }
         });
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   ansdelete = async (req, res, next) => {
      try {
         const { id } = req.params;
         await Answare.del(id);
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
   ansUpdate = async (req, res, next) => {
      try {
         const { id } = req.params;
         const { name, value } = req.body;
         if (!name || !value) return next("Data not found!");
         await Answare.update(id, () => ({ [name]: value }))
         this.call();
         return res.success("success");
      } catch (error) {
         return next(error.toString());
      }
   }
};