package pages

import (
  "log"
  "net/http"
  "net/url"
  "os"
  "strings"
  "time"

  "gitler.moe/suwako/gitlin/utils"
  "github.com/gocolly/colly"
  "github.com/gofiber/fiber/v2"
)

type (
  Commits struct {
    Date, Next, Prev string
    Commit []Commit
  }
  Commit struct {
    Mess, User, Id, IdShort, Issue, Ava string
  }
)

func HandleCommits (c *fiber.Ctx) error {
  var commitsArray []Commits
  branch := ""
  if strings.Count(c.Params("branch"), "")-1 > 0 {
    branch = c.Params("branch")
  }
  repoUrl := strings.TrimSuffix(c.Params("repo"), ".git")
  endurl := ""
  if branch != "" {
    endurl = "/" + branch
    if c.Query("after") != "" {
      endurl += "?after=" + url.QueryEscape(c.Query("after")) + "&branch=" + url.QueryEscape(c.Query("branch")) + "&qualified_name=" + url.QueryEscape(c.Query("qualified_name"))
    } else if c.Query("before") != "" {
      endurl += "?before=" + url.QueryEscape(c.Query("before")) + "&branch=" + url.QueryEscape(c.Query("branch")) + "&qualified_name=" + url.QueryEscape(c.Query("qualified_name"))
    }
  } else if (c.Query("author") != "") {
    if c.Query("after") != "" {
      endurl = "?after=" + url.QueryEscape(c.Query("after")) + "&author=" + url.QueryEscape(c.Query("author"))
    } else if c.Query("before") != "" {
      endurl = "?before=" + url.QueryEscape(c.Query("before")) + "&author=" + url.QueryEscape(c.Query("author"))
    } else {
      endurl = "?author=" + url.QueryEscape(c.Query("author"))
    }
  }

  resp, err := http.Get("https://github.com/" + c.Params("user") + "/" + repoUrl + "/commits" + endurl)
  if err != nil {
    log.Println(err)
  }
  if resp.StatusCode == 404 {
    return c.Status(404).Render("error", fiber.Map {
      "title": "Error",
      "ver": utils.Ver,
      "ves": utils.Ves,
      "error": "Repository " + c.Params("user") + "/" + repoUrl + "/commits" + endurl + " not found",
    })
  }

  Scrape := Commits{}

  ua, ok := os.LookupEnv("GITLIN_USER_AGENT")
  if !ok {
    ua = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36"
  }

  sc := colly.NewCollector(colly.AllowedDomains("github.com"), colly.UserAgent(ua))
  sc.Limit(&colly.LimitRule {
    DomainGlob: "github.githubassets.com/*",
    Delay: 30 * time.Second,
    RandomDelay: 30 * time.Second,
  })
  sc.OnRequest(func(r *colly.Request) {
    r.Headers.Set("Cache-Control", "no-cache, no-store, must-revalidate")
    r.Headers.Set("Pragma", "no-cache")
    r.Headers.Set("Expires", "0")
  })

  sc.OnHTML("div.repository-content div.container-xl div.js-navigation-container", func (e *colly.HTMLElement) {
    e.ForEach("div.TimelineItem div.TimelineItem-body", func (i int, el *colly.HTMLElement) {
      tdate := strings.TrimPrefix(el.ChildText("h2.f5"), "Commits on ")
      td, e := time.Parse("Jan 2, 2006", tdate)
      if e != nil {
        log.Println(e)
      }
      Scrape.Date = td.Format("2006年01月02日")
      el.ForEach("ol.Box", func (ij int, eli *colly.HTMLElement) {
        var mess, id, issue, idshort, user, ava string
        var commitArray []Commit

        eli.ForEach("li.Box-row", func (ijk int, elin *colly.HTMLElement) {
          mess, id, issue, idshort, user, ava = "", "", "", "", "", ""
          mess += elin.ChildText("div.Details p.mb-1 a")
          issue = strings.ReplaceAll(elin.ChildAttr("div.Details p.mb-1 a.issue-link", "href"), "https://github.com/" + c.Params("user") + "/" + repoUrl + "/pull/", "")
          id = strings.TrimPrefix(elin.ChildAttr("div.Details p.mb-1 a", "href"), "/" + c.Params("user") + "/" + repoUrl + "/commit/")
          idshort = id[:7]
          eli.ForEach("div.Details div.mt-1 div.f6", func (iju int, eliu *colly.HTMLElement) {
            user = eliu.ChildText("a")
          })
          eli.ForEach("div.Details div.d-flex div.AvatarStack div.AvatarStack-body a.avatar", func (ijh int, elia *colly.HTMLElement) {
            ava = elia.ChildAttr("img", "src")
            if (strings.Contains(ava, "https://avatars.githubusercontent.com/in")) {
              ava = strings.ReplaceAll(ava, "https://avatars.githubusercontent.com/in", "/avatar")
            } else {
              ava = strings.ReplaceAll(ava, "https://avatars.githubusercontent.com/u", "/avatar")
            }
          })
          commitArray = append(commitArray, Commit{
            Mess: mess,
            User: user,
            Id: id,
            IdShort: idshort,
            Issue: issue,
            Ava: ava,
          })
        })
        Scrape.Commit = commitArray
      })
      commitsArray = append(commitsArray, Scrape)
    })
  })

  sc.OnHTML(`div.repository-content div.container-xl div.paginate-container div.BtnGroup a:contains("Newer")`, func(e *colly.HTMLElement) {
	  Scrape.Next = strings.TrimPrefix(e.Attr("href"), "https://github.com")
  })

  sc.OnHTML(`div.repository-content div.container-xl div.paginate-container div.BtnGroup a:contains("Older")`, func(e *colly.HTMLElement) {
	  Scrape.Prev = strings.TrimPrefix(e.Attr("href"), "https://github.com")
  })

  sc.Visit("https://github.com/" + c.Params("user") + "/" + repoUrl + "/commits" + endurl)

  return c.Render("commits", fiber.Map{
    "title": c.Params("user") + "/" + repoUrl + "/commits" + endurl,
    "username": c.Params("user"),
    "reponame": repoUrl,
    "branch": branch,
    "author": c.Query("author"),
    "ver": utils.Ver,
    "ves": utils.Ves,
    "prev": Scrape.Prev,
    "next": Scrape.Next,
    "commits": commitsArray,
  })
}
