package controllers

import (
	"fmt"
	"math/rand"
	"strconv"
	"strings"
	"time"

	tele "gopkg.in/telebot.v4"
)

type DuelController struct {
	PlayerOne struct {
		ID      int64
		Counter int
		FName   string
	}

	PlayerTwo struct {
		ID      int64
		Counter int
		FName   string
	}

	Summ   int
	Inited bool
	Bot    *tele.Bot
	DC     *DataController
}

// Controller Init
func NewDuel(bot *tele.Bot, dc *DataController) *DuelController {
	return &DuelController{
		Inited: false,
		Bot:    bot,
		DC:     dc,
	}
}

// Start Match
func (s *DuelController) StartMatch(c tele.Context) error {
	if s.Inited {
		return c.Send(fmt.Sprintf("Дуэль уже началась!\nИгрок: %s\nСтавка: %d", s.PlayerOne.FName, s.Summ))
	}

	if c.Text() == "/duel" {
		return c.Send("Используйте /duel <сумма> для начала дуэли!")
	}

	s.Inited = true
	s.PlayerOne.ID = c.Sender().ID
	s.PlayerOne.FName = c.Sender().FirstName

	user := s.DC.GetUser(s.PlayerOne.ID)

	a := strings.Split(c.Text(), "/duel ")[1]
	summ, err := strconv.Atoi(a)
	if err != nil {
		return c.Send("Некорректная команда, используйте /duel <сумма>")
	} else {
		s.Summ = summ
	}

	if user.DickSize < summ {
		return c.Send("У вас недостаточно длинный пенис для состязания!")
	}

	if summ <= 0 {
		return c.Send("Некорректная сумма, используйте положительное значение!")
	}

	return c.Send(fmt.Sprintf("%s начал дуель, ставка: %d", s.PlayerOne.FName, summ))
}

// Accept Match
func (s *DuelController) AcceptMatch(c tele.Context) error {
	if !s.Inited {
		return c.Send("Дуэль еще не началась! Дождитесь старта матча или начните новую дуель с помощью /duel <сумма>")
	}

	s.PlayerTwo.ID = c.Sender().ID
	s.PlayerTwo.FName = c.Sender().FirstName

	user := s.DC.GetUser(s.PlayerTwo.ID)

	if user.DickSize < s.Summ {
		return c.Send("У вас недостаточно длинный пенис для состязания!")
	}

	if s.PlayerTwo.ID == s.PlayerOne.ID {
		return c.Send("Вы не можете принять участие в своей же дуэли!")
	}

	s.Summ *= 2
	go s.gameProccess(c.Chat())

	return c.Send(fmt.Sprintf("%s принимает участие в дуэли.", s.PlayerTwo.FName))
}

// Start Game
func (s *DuelController) gameProccess(r tele.Recipient) {
	time.Sleep(time.Second * 3)
	s.Bot.Send(r, fmt.Sprintf("Дуэль началась!\nНа кону: %d", s.Summ))
	s.RoundOne(r)
}

// Round One
func (s *DuelController) RoundOne(r tele.Recipient) {
	time.Sleep(time.Second * 3)
	s.PlayerOne.Counter += rand.Intn(11) + 1
	s.PlayerTwo.Counter += rand.Intn(11) + 1
	s.Bot.Send(r,
		fmt.Sprintf("Результаты первого раунда\nИгрок %s: %d очков.\nИгрок %s: %d очков.",
			s.PlayerOne.FName, s.PlayerOne.Counter, s.PlayerTwo.FName, s.PlayerTwo.Counter),
	)
	s.RoundTwo(r)
}

// Round Two
func (s *DuelController) RoundTwo(r tele.Recipient) {
	time.Sleep(time.Second * 3)
	s.PlayerOne.Counter += rand.Intn(11) + 1
	s.PlayerTwo.Counter += rand.Intn(11) + 1
	s.Bot.Send(r,
		fmt.Sprintf("Результаты второго раунда\nИгрок %s: %d очков.\nИгрок %s: %d очков.",
			s.PlayerOne.FName, s.PlayerOne.Counter, s.PlayerTwo.FName, s.PlayerTwo.Counter),
	)
	s.RoundThree(r)
}

// Round Three
func (s *DuelController) RoundThree(r tele.Recipient) {
	time.Sleep(time.Second * 3)
	s.PlayerOne.Counter += rand.Intn(11) + 1
	s.PlayerTwo.Counter += rand.Intn(11) + 1
	s.Bot.Send(r,
		fmt.Sprintf("Результаты третьего раунда\nИгрок %s: %d очков.\nИгрок %s: %d очков.",
			s.PlayerOne.FName, s.PlayerOne.Counter, s.PlayerTwo.FName, s.PlayerTwo.Counter),
	)
	s.CheckWin(r)
}

// Check Win
func (s *DuelController) CheckWin(r tele.Recipient) {
	userOne := s.DC.GetUser(s.PlayerOne.ID)
	userTwo := s.DC.GetUser(s.PlayerTwo.ID)
	time.Sleep(time.Second * 3)
	var winner int = 0
	if s.PlayerOne.Counter > s.PlayerTwo.Counter {
		winner = 1
	} else {
		winner = 2
	}

	if winner == 1 {
		s.Inited = false
		s.Bot.Send(r, fmt.Sprintf("Игрок %s победил!", s.PlayerOne.FName))
		s.DC.UpdateDick(userOne.ID, userOne.DickSize+(s.Summ/2))
		s.DC.UpdateDick(userTwo.ID, userTwo.DickSize-(s.Summ/2))
	} else if winner == 2 {
		s.Inited = false
		s.Bot.Send(r, fmt.Sprintf("Игрок %s победил!", s.PlayerTwo.FName))
		s.DC.UpdateDick(userOne.ID, userOne.DickSize-(s.Summ/2))
		s.DC.UpdateDick(userTwo.ID, userTwo.DickSize+(s.Summ/2))
	} else {
		s.Inited = false
		s.Bot.Send(r, "Ничья!")
	}
}
