package bot

import (
	"bordrobot/lib/company"
	"bordrobot/lib/model"
	"bordrobot/lib/ocr"
	"fmt"
	"io/ioutil"
	"log"
	"regexp"
	"strings"
	"time"

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

type Luca struct {
	Page    *rod.Page
	Browser *rod.Browser
}

func websiteMessage(page *rod.Page, selector string, searchValue string) (string, error) {
	// Tek bir öğe alınması, hata durumunu kontrol etmek için
	elemd := page.MustElements(selector)

	// Eğer elem boş ise, yani nil ise, hata döndür
	if len(elemd) == 0 {
		err := fmt.Errorf("Sellector Bulunamadı: %v", selector)
		return "", err
	}
	elem := page.MustElement(selector)
	// Eğer elem boş ise, yani nil ise, hata döndür
	if elem == nil {
		err := fmt.Errorf("Sellector Bulunamadı: %v", selector)
		return "", err
	}

	// Öğenin metnini al
	//text := elem.MustEval(fmt.Sprintf(`() => this.%s`, searchValue)).String()
	//	text := elem.MustEval(`() => this.innerText`).String()
	text := elem.MustEval(fmt.Sprintf(`() => this.%s`, searchValue)).String()

	return text, nil
}
func clickItem(frm *rod.Page, selector string, clickCount int) error {
	// Sayfadan ilgili öğeyi bul
	dd, err := frm.Element(selector)
	err = dd.Click(proto.InputMouseButtonLeft, clickCount)
	if err != nil {
		return err
	}

	return nil
}

// func (elemSelector *rod.Element)SelectItem(frm *rod.Page, selector string, changeValue string) error {
// 	elemSelector.Eval(`document.getElementById("` + selector + `").value = "` + changeValue + `";`)
// 	elemSelector.Eval(`document.getElementById("` + selector + `").dispatchEvent(new Event('change'));`)
// 	// _, err := frm.Evaluate(rod.Eval(`
// 	// 	document.getElementById("` + selector + `").value = "` + changeValue + `";
// 	// `))
// 	// _, err = frm.Evaluate(rod.Eval(`
// 	// 	document.getElementById("` + selector + `").dispatchEvent(new Event('change'));
// 	// `))
// 	return err

// }
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) error {
	page := l.Page
	page.MustElement("#musteriNo").MustInput(company.MemberNumber)
	page.Timeout(500)
	page.MustElement("#kullaniciAdi").MustInput(company.Username)
	page.Timeout(500)
	page.MustElement("#parola").MustInput(company.Password)
	page.Timeout(500)
	page.MustWaitNavigation()

	result, err := page.Evaluate(rod.Eval(`document.getElementById(girisbtn())`))
	if err != nil {
	}
	page.Timeout(500)
	loginDialog := "body > div.swal2-container.swal2-fade.swal2-in > div > div.swal2-content" // Örneğinizdeki CSS seçicisini buraya yazın
	loginDialogMessage, err := websiteMessage(page, loginDialog, "innerText")
	if err != nil {
		fmt.Errorf("hata verdi handle")
	}
	if loginDialogMessage == "Müşteri No, Kullanıcı Adı veya Parola hatalıdır." {
		fmt.Println("Şifre hatalı")
	}
	var captchaMsg []string
	getUrl := page.MustInfo().URL
	splitUrl := strings.Split(getUrl, "/")
	splitUrlPage := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
	if splitUrlPage != "main.erp" {
		captcha := "#captcha" // Örneğinizdeki CSS seçicisini buraya yazın
		wait := page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err := page.Evaluate(rod.Eval(`document.getElementsByTagName("body")[0].style.backgroundImage = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik1")[0].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik2")[0].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = "none"`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()

		datas, err := page.Screenshot(true, &proto.PageCaptureScreenshot{})
		if err != nil {
			panic(err)
		}
		err = ioutil.WriteFile("C:/Users/huseyin/Desktop/project/notitek/BordroRobot/app/lib/ocr/screenshot.png", datas, 0644)
		if err != nil {
			panic(err)
		}
		captchaMessage, err := websiteMessage(page, captcha, "src")
		_, err = page.Evaluate(rod.Eval(`document.getElementsByTagName("body")[0].style.backgroundImage = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik1")[0].style.display = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik2")[0].style.display = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[1].style.display = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[2].style.display = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[3].style.display = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[4].style.display = ""`))
		wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		wait()
		_, err = page.Evaluate(rod.Eval(`document.getElementsByClassName("baslik3")[0].getElementsByClassName("inp")[5].style.display = ""`))
		captchaMsg, err = ocr.VisionApi("C:/Users/huseyin/Desktop/project/notitek/BordroRobot/app/lib/ocr/screenshot.png")
		if captchaMessage != "" {
			splitUrlPage = "captcha"
		}
		if err != nil {
			fmt.Errorf("captcha Getirilirken hata oluştu")
		}
		//fmt.Println(captchaMessage) //sil
	}
	fmt.Println(result) //sil

	//page.MustElement("#captcha-input").MustInput(captchaMessage)

	switch splitUrlPage {
	case "giris.erp":
		rod.Eval(`document.querySelector("body > div.swal2-container.swal2-fade.swal2-in > div > button.swal2-confirm.swal2-styled").click()`)
		//kullanıcı adı ve şifre yanlış hatası verecek error basılacak
	case "captcha":
		captchaString := captchaMsg[0]
		page.MustElement("#captcha-input").MustInput(strings.Trim(captchaString, " "))
		captchaButton, err := page.Evaluate(rod.Eval(`document.getElementById(document.forms[0].submit())`))
		if err != nil {
		}
		fmt.Println("Sonuç:", captchaButton)
		getUrl = page.MustInfo().URL
		splitUrl = strings.Split(getUrl, "/")
		uri := strings.Split(splitUrl[len(splitUrl)-1], ";")[0]
		if uri != "main" {
			fmt.Println("captcha tekrar deneme fonksiyonuna sok")
			//captcha tekrar denenecek
		}
	}
	wait := page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
	wait()

	_, err = page.Evaluate(rod.Eval(`gonder('formTarget');`))

	wait = page.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
	wait()
	return err

}
func (l *Luca) NavigateBordroGiris() error {
	return nil
}

func (l *Luca) BordroYaz(data []*model.Bordro) error {
	page := l.Page
	allPages, err := page.Browser().Pages()
	if err != nil {
		log.Fatal(err)
	}

	newPage, err := allPages.FindByURL("https://auygs.luca.com.tr/Luca/luca.do")
	if err != nil {
		log.Fatal(err)
	}

	//fs4, err := newPage.Element("#frm4")
	//if err != nil {
	//	log.Fatal(err)
	//}
	fs2, err := newPage.Element("#frm2")
	if err != nil {
		log.Fatal(err)
	}
	frame, err := fs2.Frame()
	fs3, err := newPage.Element("#frm3")
	if err != nil {
		log.Fatal(err)
	}
	frame3, err := fs3.Frame()
	err = newPage.WaitLoad()
	//_, err = fs2.Evaluate(rod.Eval(`document.getElementById('apy1000m0i1ITD').dispatchEvent(new MouseEvent('mouseover', { 'bubbles': true }));`))
	err = clickItem(frame, "#apy1000m0i1ITD", 1)
	fmt.Println(err)
	err = clickItem(frame3, "#apy1000m33i4ITX", 1)
	fmt.Println(err)
	err = newPage.WaitLoad()
	wait := newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
	wait()
	isyeriSelectBox, err := websiteMessage(frame3, "#isyeriId", "innerHTML")
	if err != nil {
		log.Fatal(err)
	}
	wait = newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
	wait()

	wait = newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
	wait()

	for i := 0; i < len(data); i++ {
		options := strings.Split(isyeriSelectBox, "</option>")
		vls := ""
		bolum := ""

		for _, option := range options {
			// "value" ve metin içeriğini almak için regex kullanma
			re := regexp.MustCompile(`value="(.+)"[^>]*>([^<]+)`)
			matches := re.FindStringSubmatch(option)
			if len(matches) >= 3 {
				value := matches[1]
				text := matches[2]

				// "BESMART" değerini içeren option öğelerini bulma
				if text == data[0].Sube.Value {
					vls = value
					break
				}
			}
		}

		isyeriId := vls
		element, err := frame3.Element("#isyeriId")
		selectInput := Select{Element: element, Selector: "#isyeriId"}
		selectInput.SelectItem(isyeriId)

		err = WaitLoad(frame3)
		if err != nil {
			return err
		}
		bolumSelectBox, err := websiteMessage(frame3, "#bolumId", "innerHTML")
		fmt.Println(bolumSelectBox)
		bolums := strings.Split(bolumSelectBox, "</option>")
		for _, option := range bolums {
			// "value" ve metin içeriğini almak için regex kullanma
			re := regexp.MustCompile(`value="(.+)"[^>]*>([^<]+)`)
			matches := re.FindStringSubmatch(option)
			if len(matches) >= 3 {
				value := strings.Trim(matches[1], " ")
				text := strings.Trim(matches[2], " ")

				// "BESMART" değerini içeren option öğelerini bulma
				if text == "FİNANS" {
					bolum = value
					break
				}
			}
		}

		bolumId := bolum
		element, err = frame3.Element("#bolumId")
		selectInput = Select{Element: element, Selector: "#bolumId"}
		selectInput.SelectItem(bolumId)

		err = WaitLoad(frame3)
		if err != nil {
			return err
		}
		// wait = newPage.WaitRequestIdle(500*time.Millisecond, nil, nil, nil)
		// wait()
		aktarimDonem := "1"
		err = clickItem(frame3, "#tr"+aktarimDonem+" > td:nth-child(1)", 2)
		if err != nil {
			log.Fatal(err)
		}
		personel := data[i].TCKimlikNo //"54853109724"
		fmt.Println(personel)
		err = WaitLoad(frame3)
		if err != nil {
			return err
		}

		// wait = newPage.WaitRequestIdle(1000*time.Millisecond, nil, nil, nil)
		// wait()
		//var targetID string
		elems, err := frame3.Elements("#scroll > table > tbody > tr > td[id^='tcKimlikNo']")
		trs, err := frame3.Elements("#scroll > table > tbody > tr")
		var foundIndex int = -1
		for i := 0; i < len(elems); i++ {
			tex, err := elems[i].Text()
			if err != nil {
				return err
			}
			if tex == data[i].TCKimlikNo.Value {
				//targetID = tex
				foundIndex = i
				break
			}
			fmt.Print(elems, tex)
		}
		if foundIndex != -1 {
			trs[foundIndex].Click(proto.InputMouseButtonLeft, 2)
		}
		err = WaitLoad(frame3)
		if err != nil {
			return err

		}
		data[i].FillBordroForm(frame3)
		//err yoksa hesapla ba
		calculate, err := frame3.Element("body > form > table > tbody > tr.altBar.alt-button-bar > th > table > tbody > tr > td.right > button")
		if err != nil {
			return err
		}
		calculate.Click(proto.InputMouseButtonLeft, 1)
		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)")
		if err != nil {
			return err
		}
		newBordroPage.Click(proto.InputMouseButtonLeft, 1)
		err = WaitLoad(frame3)
		if err != nil {
			return err

		}
	}
	return err

}

// func (l *Luca)pageInsert(data, b* model.PageStruct){

// }

//type Luca struct {
//}
//
//func NewLucaBot() *Luca {
//	return &Luca{}
//}
//func (l *Luca) Login() error {
//	return nil
//}
//func (l *Luca) NavigateBordroGiris() error {
//	return nil
//}
//
//func (l *Luca) BordroYaz(b *model.Bordro) {
//
//}
