package bot

import (
	"bordrobot/lib/company"
	"bordrobot/lib/helper"
	"bordrobot/lib/ocr"
	"errors"
	"fmt"
	"io/ioutil"
	"strconv"
	"strings"
	"time"

	"github.com/go-rod/rod"
	"github.com/go-rod/rod/lib/launcher"
	"github.com/go-rod/rod/lib/proto"
)

var pageErrors []string
var scriptIndexArray []BordroPageScript

type Luca struct {
	Page    *rod.Page
	Browser *rod.Browser
}
type errorInfo struct {
	Error string
	Index int
}
type BordroPageScript struct {
	Index string
	Value string
}

func (l *Luca) ErrFunc(index bool) {
	if index {
		CloseBrowser(l.Browser)
	}
}
func VerifyCaptcha(page *rod.Page) error {
	captcha := "#captcha"
	picturePreparation := []string{
		`document.getElementsByTagName("body")[0].style.backgroundImage = "none"`,
		`document.getElementsByClassName("baslik1")[0].style.display = "none"`,
		`document.getElementsByClassName("baslik2")[0].style.display = "none"`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = "none"`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = "none"`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = "none"`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = "none"`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = "none"`,
	}
	for i := 0; i < len(picturePreparation); i++ {
		wait := page.WaitRequestIdle(600*time.Millisecond, nil, nil, nil)
		wait()
		_, err := page.Evaluate(rod.Eval(`()=>{` + picturePreparation[i] + `}`))
		if err != nil {
			return err
		}
		fmt.Print(err)
	}
	datas, err := page.Screenshot(true, &proto.PageCaptureScreenshot{})
	if err != nil {
		panic(err)
	}

	err = helper.CreateFolder("./processFolder")
	err = ioutil.WriteFile("./processFolder/screenshot.png", datas, 0644)
	if err != nil {
		panic(err)
	}
	captchaMessage, err := ReceiveDOMMessages(page, captcha, "src")
	picturePreparation = []string{
		`document.getElementsByTagName("body")[0].style.backgroundImage = ""`,
		`document.getElementsByClassName("baslik1")[0].style.display = ""`,
		`document.getElementsByClassName("baslik2")[0].style.display = ""`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = ""`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = ""`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = ""`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = ""`,
		`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = ""`,
	}
	for i := 0; i < len(picturePreparation); i++ {
		wait := page.WaitRequestIdle(600*time.Millisecond, nil, nil, nil)
		wait()
		_, err := page.Evaluate(rod.Eval(`()=>{` + picturePreparation[i] + `}`))
		if err != nil {
			return err
		}
		fmt.Print(err)
	}
	var captchaMsg []string

	captchaMsg, err = ocr.VisionApi("./processFolder/screenshot.png")
	fmt.Print(captchaMessage)

	trimmedMsg := strings.ReplaceAll(captchaMsg[0], " ", "")
	page.MustElement("#captcha-input").MustInput(strings.ToLower(trimmedMsg))
	_, err = page.Evaluate(rod.Eval(`document.getElementById(document.forms[0].submit())`))
	if err != nil {
	}
	err = WaitLoad(page)
	if err != nil {
		return err
	}
	getUrl := page.MustInfo().URL
	splitUrl := strings.Split(getUrl, "/")
	uri := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
	if uri != "main.erp" {
		_, err = page.Evaluate(rod.Eval(`document.querySelector("body > div.swal2-container.swal2-fade.swal2-in > div > button.swal2-confirm.swal2-styled").click()`))
		//rod.Eval(`document.querySelector("body > div.swal2-container.swal2-fade.swal2-in > div > button.swal2-confirm.swal2-styled").click()`)

		VerifyCaptcha(page)
		fmt.Println("captcha tekrar deneme fonksiyonuna sok")
		//captcha tekrar denenecek
	}
	return nil

}
func NewLucaBot() *Luca {
	l := launcher.New().
		Headless(false).
		Devtools(true)

	//defer l.Cleanup()

	url := l.MustLaunch()
	browser := rod.New().
		ControlURL(url).
		Trace(true).
		//SlowMotion(1 * time.Second).
		MustConnect()
	page := browser.MustPage("https://agiris.luca.com.tr/LUCASSO/giris.erp")
	fmt.Println(page)

	return &Luca{Page: page, Browser: browser}
}

func (l *Luca) Login(company company.Company, month float64, year float64) error {
	page := l.Page
	err := WaitLoad(page)
	if err != nil {
		return err
	}
	err = FillInput(page, "#musteriNo", company.MemberNumber)
	if err != nil {
		return err
	}
	page.Timeout(500)
	err = FillInput(page, "#kullaniciAdi", company.Username)
	if err != nil {
		return err
	}
	page.Timeout(500)
	err = FillInput(page, "#parola", company.Password)
	if err != nil {
		return err
	}
	page.Timeout(500)

	result, err := page.Evaluate(rod.Eval(`()=>{girisbtn()}`))
	if err != nil {
		return err
	}
	page.Timeout(1000)
	loginDialog := "body > div.swal2-container.swal2-fade.swal2-in > div > div.swal2-content"

	loginDialogMessage, err := ReceiveDOMMessages(page, loginDialog, "innerText")
	if err != nil {
		errString := err.Error()
		if !strings.Contains(errString, "Sellector Bulunamadı") {
			return err
		}
	}
	if loginDialogMessage == "Müşteri No, Kullanıcı Adı veya Parola hatalıdır." {
		return errors.New("Şifre hatalı")

	}
	err = WaitLoad(page)
	if err != nil {
		return err
	}
	getUrl := page.MustInfo().URL
	splitUrl := strings.Split(getUrl, "/")
	splitUrlPage := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
	if splitUrlPage != "main.erp" {
		VerifyCaptcha(page)
	}
	fmt.Println(result)
	wait := page.WaitRequestIdle(1000*time.Millisecond, nil, nil, nil)
	wait()

	_, err = page.Evaluate(rod.Eval(`()=>{gonder('formTarget');}`))
	if err != nil {
		return err
	}

	Wait(page, 2000)

	allPages, err := page.Browser().Pages()
	if err != nil {
		return err
	}

	newPage, err := allPages.FindByURL("https://auygs.luca.com.tr/Luca/luca.do")
	err = WaitLoad(newPage)
	if err != nil {
		return err
	}
	frm4, err := newPage.Element("#frm4")
	if err != nil {
		return err
	}
	frame4, err := frm4.Frame()
	Wait(frame4, 1500)
	err = WaitLoad(newPage)
	if err != nil {
		return err
	}
	companiesSelectBoxWait, err := frame4.Element("#SirketCombo > option")
	if err != nil {
		return err
	}
	err = companiesSelectBoxWait.WaitLoad()
	if err != nil {
		return err
	}
	companiesSelectBox, err := frame4.Elements("#SirketCombo > option")
	if err != nil {
		return err
	}
	var vls string = ""
	for j := 0; j < len(companiesSelectBox); j++ {
		tex, err := companiesSelectBox[j].Text()
		value, err := companiesSelectBox[j].Property("value")
		if err != nil {
			return err
		}
		if err != nil {
			return err
		}
		if tex == company.Name {
			vls = value.String()
			break
		}
	}
	Wait(newPage, 500)
	element, err := frame4.Element("#SirketCombo")
	if err != nil {
		return err
	}
	selectInput := Select{Element: element, Selector: "#SirketCombo"}
	err = selectInput.SelectItem(vls)
	if err != nil {
		return err
	}
	err = WaitLoad(frame4)
	if err != nil {
		return err
	}
	companiesSelectYear, err := frame4.Elements("#DonemCombo > option")

	if err != nil {
		return err
	}
	for j := 0; j < len(companiesSelectYear); j++ {
		tex, err := companiesSelectYear[j].Text()
		value, err := companiesSelectYear[j].Property("value")
		if err != nil {
			return err
		}
		if err != nil {
			return err
		}
		if strings.Contains(tex, strconv.Itoa(int(year))) {
			vls = value.String()
			break
		}
	}
	Wait(newPage, 500)
	element, err = frame4.Element("#DonemCombo")
	if err != nil {
		return err
	}
	selectInput = Select{Element: element, Selector: "#DonemCombo"}
	err = selectInput.SelectItem(vls)
	if err != nil {
		return err
	}
	err = WaitLoad(frame4)
	if err != nil {
		return err
	}

	err = ClickItem(frame4, "#SirName > button.no-bold.green > i", 1)

	err = WaitLoad(frame4)
	if err != nil {
		return err
	}
	Wait(newPage, 500)

	return err
}

func (l *Luca) BordroTableMaping(frame *rod.Page, b *LucaBordro) ([]BordroPageScript, error) {
	table, err := frame.Elements("#scroll > div > table > tbody > tr > td > table > tbody > tr > td") //table kontrol et var mı yok mu diye
	if err != nil {
		return nil, err
	}
	//table := frame.MustElements(".i2")
	var mainText string
	for t := 0; t < len(table); t++ {
		if t == 150 {
			fmt.Print("asda")
		}
		inputElement, err := table[t].Element("input")
		text, err := table[t].Text()
		fmt.Print(mainText)
		if text != "" {
			mainText = text
		}
		if inputElement != nil {
			if mainText != "" {
				fmt.Print(t)
				inputElement, err := table[t+1].Element("input")
				if inputElement == nil {
					mainText = ""
					fmt.Print("Hatalı Text")
					continue
				}
				id, err := inputElement.Attribute("id")

				fmt.Print(err)
				pageScript := BordroPageScript{
					Value: text,
					Index: *id,
				}
				scriptIndexArray = append(scriptIndexArray, pageScript)
				fmt.Println("Text:", text)
				fmt.Println("ID:", *id)
				fmt.Println("--------------------")
				mainText = ""
			}

		}
		// Satırın özelliklerini al

		// Satırın textini al

		fmt.Print(err)

		// for k, v := range b.Ucretler {
		// 	fmt.Print(v, k)
		// 	//table'da key--> k i bul,
		// 	//takip eden ilk td'deki ilk input'a v'yi yaz
		// 	//table'da k'yi bulmazsan ve v de değer varsa hata dön
		// 	if strings.Contains(text, k) {
		// 		Id := ""
		// 		if id != nil {
		// 			Id = *id
		// 			fmt.Println("ID:", *id)
		// 		} else {
		// 			Id = ""
		// 		}
		// 		pageScript := BordroPageScript{
		// 			Value: text,
		// 			Index: Id,
		// 		}

		// 		scriptIndexArray = append(scriptIndexArray, pageScript)
		// 		break
		// 	}
		// }
		// Sonuçları yazdır         ///text boşsa id de boş oluyo

	}
	return scriptIndexArray, nil
}
func (l *Luca) PayrollPageLogin() error {
	newPage, err := l.GetPageByUrl("https://auygs.luca.com.tr/Luca/luca.do")
	if err != nil {
		return err
	}

	fs2, err := newPage.Element("#frm2")
	if err != nil {
		return err
	}
	frame, err := fs2.Frame()
	fs3, err := newPage.Element("#frm3")
	if err != nil {
		return err
	}
	frame3, err := fs3.Frame()
	err = newPage.WaitLoad()
	if err != nil {
		return err
	}
	Wait(newPage, 200)
	err = ClickItem(frame, "#apy1000m0i1ITD", 1)
	if err != nil {
		return err
	}
	fmt.Println(err)
	err = ClickItem(frame3, "#apy1000m33i4ITX", 1)
	if err != nil {
		return err
	}
	err = newPage.WaitLoad()
	if err != nil {
		return err
	}
	Wait(newPage, 1500)
	err = WaitLoad(frame3)
	if err != nil {
		return err
	}
	return err
}

func (l *Luca) BordroYaz(month, year int, b *LucaBordro, lastItem bool) error {
	newPage, err := l.GetPageByUrl("https://auygs.luca.com.tr/Luca/luca.do")
	if err != nil {
		return err
	}
	frame3, err := l.GetFrame(newPage, "#frm3")
	if err != nil {
		return err
	}
	isyeriId := ""
	bolumId := ""
	bordroCompanySelectBox, err := frame3.Elements("#isyeriId > option")
	for j := 0; j < len(bordroCompanySelectBox); j++ {
		text, err := bordroCompanySelectBox[j].Text()
		value, err := bordroCompanySelectBox[j].Property("value")
		if err != nil {
			return err
		}
		if strings.Trim(text, " ") == b.Sube { //.Sube.Value
			isyeriId = value.String()
			break
		}
	}

	element, err := frame3.Element("#isyeriId")
	element.WaitLoad()
	if err != nil {
		return err
	}
	selectInput := Select{Element: element, Selector: "#isyeriId"}
	err = selectInput.SelectItem(isyeriId)
	if err != nil {
		return err
	}
	err = WaitLoad(frame3)
	if err != nil {
		return err
	}
	bordroDepartmentSelectBox, err := frame3.Elements("#bolumId > option")
	element, err = frame3.Element("#bolumId > option")
	element.WaitLoad()
	if err != nil {
		return err
	}
	for j := 0; j < len(bordroDepartmentSelectBox); j++ {
		text, err := bordroDepartmentSelectBox[j].Text()
		value, err := bordroDepartmentSelectBox[j].Property("value")
		if err != nil {
			return err
		}
		if strings.Trim(text, " ") == b.Bolum { //.Bolum.Value
			bolumId = value.String()
			break
		}
		fmt.Print(text, value)
	}

	element, err = frame3.Element("#bolumId")
	if err != nil {
		return err
	}
	selectInput = Select{Element: element, Selector: "#bolumId"}
	err = selectInput.SelectItem(bolumId)
	if err != nil {
		return err
	}
	err = WaitLoad(frame3)
	if err != nil {
		return err
	}
	err = ClickItem(frame3, "#tr"+strconv.FormatFloat(float64(month), 'f', -1, 64)+" > td:nth-child(1)", 2) //aktarım ayı
	if err != nil {
		return err
	}
	err = WaitLoad(frame3)
	if err != nil {
		return err
	}

	var isEmpty bool = false
	//var targetID string
	elems, err := frame3.Elements("#scroll > table > tbody > tr > td[id^='tcKimlikNo']")
	if err != nil {
		return err
	}
	elemsProcess, err := frame3.Elements("#scroll > table > tbody > tr > td > a")
	if err != nil {
		return err
	}
	trs, err := frame3.Elements("#scroll > table > tbody > tr")
	if err != nil {
		return err
	}
	var foundIndex int = -1
	if len(elems) == 0 {
		err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(3)", 1)
		if err != nil {
			return err
		}
		err = WaitLoad(frame3)
		if err != nil {
			return err
		}
		l.ErrFunc(lastItem)
		return errors.New("Böyle Bir Kullanıcı Bulunamadı")
	}
	for j := 0; j < len(elems); j++ {
		tex, err := elems[j].Text()
		if err != nil {
			return err
		}
		process, err := elemsProcess[j].Text()
		if err != nil {
			return err
		}
		if tex == b.TcNo { //.TCKimlikNo.Value
			foundIndex = j
			if process == "Bordro Sil" {
				isEmpty = true
			}
			break
		}
		fmt.Print(elems, tex)
	}
	if isEmpty == true {
		err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(3)", 1)
		if err != nil {
			return err
		}
		err = WaitLoad(frame3)
		if err != nil {
			return err
		}
		l.ErrFunc(lastItem)
		return errors.New("Yazılı Bordro Var Lütfen Siliniz")
	}
	if foundIndex != -1 && isEmpty == false {

		trs[foundIndex].Click(proto.InputMouseButtonLeft, 2)
	}
	Wait(newPage, 1500)
	err = WaitLoad(frame3)
	if err != nil {
		return err

	}
	rsp, err := l.BordroTableMaping(frame3, b)
	if len(rsp) == 0 {
		//hata ver
	}
	fmt.Print(rsp)
	//rsp den dönden değerler ile matchlencek ve yazılcak
	for k, v := range b.Ucretler {
		for i := 0; i < len(rsp); i++ {
			if k == rsp[i].Value {

				el, err := frame3.Element("#" + rsp[i].Index)
				if err != nil {
					return err
				}
				err = el.Input(v.String())
			}
		}
		fmt.Print(v, k)

	}
	err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td.right > button", 1)
	if err != nil {
		return err
	}
	saveButtonMessage, err := ReceiveDOMMessages(frame3, ".alert-container", "innerText")
	if err != nil {
		return err
	}
	if saveButtonMessage != "Bordro hesaplanıyor." {
		newBordroPage, err := frame3.Element("body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(4)")
		newBordroPage.WaitLoad()
		if err != nil {
			return err
		}
		newBordroPage.Click(proto.InputMouseButtonLeft, 1)
		err = WaitLoad(frame3)
		if err != nil {
			return err

		}
		err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(3)", 1)

		if err != nil {
			return err

		}
		l.ErrFunc(lastItem)
		return errors.New(saveButtonMessage)
	}

	err = WaitLoad(frame3)
	if err != nil {
		return err
	}
	newBordroPage, err := frame3.Element("body > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(4)")
	newBordroPage.WaitLoad()
	if err != nil {
		return err
	}
	newBordroPage.Click(proto.InputMouseButtonLeft, 1)
	err = WaitLoad(frame3)
	if err != nil {
		return err

	}
	err = ClickItem(frame3, "body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td:nth-child(1) > button:nth-child(3)", 1)

	if err != nil {
		return err
	}
	l.ErrFunc(lastItem)
	return err
}
