package handlers

import (
	"fmt"
	"go.uber.org/zap"
	"net/http"
	"time"
)

func (h *Handlers) IndexPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Homepage"}
	user := getJwtUser(r)
	if user != nil {
		data["User"] = user

		// Yandex OAuth
		yaData, err := h.dal.YaDisk.GetListByUserID(r.Context(), user.UserID)
		if err != nil {
			h.reportError(w, err, http.StatusInternalServerError)
			return
		}

		if yaData == nil {
			data["YandexUrl"] = h.YaDisk.GenerateOAuthUrl()
		} else if yaData[0].Token() == nil {
			data["YandexUrl"] = h.YaDisk.GenerateOAuthUrl()
		} else {
			templates, err := h.dal.Template.GetListByUserIDAndStorage(r.Context(), user.UserID, "yadisk")
			if err != nil {
				h.logger.Error("ErrorHandler", zap.Error(err))
			}
			data["YaDiskTemplates"] = templates
		}

		// Google OAuth
		googleData, err := h.dal.GDisk.GetListByUserID(r.Context(), user.UserID)
		if err != nil {
			h.reportError(w, err, http.StatusInternalServerError)
			return
		}

		if googleData == nil {
			data["GoogleUrl"] = h.GDisk.GenerateOAuthUrl()
		} else {
			templates, err := h.dal.Template.GetListByUserIDAndStorage(r.Context(), user.UserID, "gdisk")
			if err != nil {
				h.logger.Error("ErrorHandler", zap.Error(err))
			}
			data["GDiskTemplates"] = templates
		}

		// Amo OAuth
		amoInfo, err := h.dal.Amo.GetListByUserID(r.Context(), user.UserID)
		if err != nil {
			h.reportError(w, err, 500)
		}

		if amoInfo == nil || amoInfo[0].Token().AccessToken == "" {
			data["AmoUrl"] = h.Amo.GenerateOAuthUrl()
		}

	}

	err := execTemplate("index.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) RegistrationPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Registration"}

	user := getJwtUser(r)
	if user != nil {
		data["User"] = user
	}

	err := execTemplate("registration.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) LoginPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Login"}
	user := getJwtUser(r)
	if user != nil {
		data["User"] = user
	}

	err := execTemplate("login.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) YaDiskPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Yandex Disk"}

	user := getJwtUser(r)
	if user != nil {
		data["User"] = user
		// Yandex OAuth
		yaData, err := h.dal.YaDisk.GetListByUserID(r.Context(), user.UserID)
		if err != nil {
			h.reportError(w, err, http.StatusInternalServerError)
			return
		}

		if yaData == nil {
			data["YandexUrl"] = h.YaDisk.GenerateOAuthUrl()
		} else if yaData[0].Token() == nil {
			data["YandexUrl"] = h.YaDisk.GenerateOAuthUrl()
		} else {
			client, err := h.YaDisk.NewClient(r.Context(), yaData[0].Token(), "")
			if err != nil {
				h.reportError(w, err, 500)
				return
			}

			disk, err := client.GetDisk()
			if err != nil {
				h.reportError(w, err, 500)
				return
			}

			data["YaDiskInfo"] = disk

			data["YaDisk"] = yaData[0]

			templateFolderData, err := client.GetResources(yaData[0].TemplateFolder)
			if err != nil {
				h.reportError(w, err, 500)
				return
			}

			var templateFolder []map[string]interface{}

			for _, item := range templateFolderData.Embedded.Items {
				dataItem := map[string]interface{}{
					"Name": item.Name,
					"Size": item.Size,
					"File": item.File,
				}
				template, err := h.dal.Template.GetByFilenameAndUserID(r.Context(), item.Name, user.UserID)
				if err != nil {
					h.logger.Error("ErrorHandler", zap.Error(err))
				}

				if template != nil {
					dataItem["Event"] = template.Name
				} else {
					dataItem["Event"] = "Nil"
				}

				templateFolder = append(templateFolder, dataItem)
			}

			if templateFolder != nil {
				data["YaDiskTemplateFolder"] = templateFolder
			}

			saveFolderData, err := client.GetResources(yaData[0].SaveFolder)
			if err != nil {
				h.reportError(w, err, 500)
				return
			}

			var saveFolder []map[string]interface{}

			for _, item := range saveFolderData.Embedded.Items {
				saveFolder = append(templateFolder, map[string]interface{}{
					"Name": item.Name,
					"Size": templateFolderData.Size,
					"File": templateFolderData.File,
				})
			}

			if saveFolder != nil {
				data["YaDiskTemplateFolder"] = templateFolder
			}
		}
	}

	err := execTemplate("YaDisk.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) GDiskPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Google Disk"}

	user := getJwtUser(r)
	if user != nil {

		// Google OAuth
		googleData, err := h.dal.GDisk.GetListByUserID(r.Context(), user.UserID)
		if err != nil {
			h.reportError(w, err, http.StatusInternalServerError)
			return
		}

		if googleData == nil {
			data["GoogleUrl"] = h.GDisk.GenerateOAuthUrl()
		} else {
			token := googleData[0].Token()
			if time.Now().After(token.Expiry) {
				fmt.Println("Token expired:", token)
				token, err = h.GDisk.RefreshToken(r.Context(), token)
				if err != nil {
					h.reportError(w, err, 500)
				}
				fmt.Println("Updated token:", token)
				//h.GDisk.GetToken()
			}

			client, err := h.GDisk.NewClient(r.Context(), token)
			if err != nil {
				h.reportError(w, err, 500)
				return
			}

			client.GetDisk()

			if err != nil {
				h.reportError(w, err, 500)
				return
			}
			data["GDisk"] = googleData[0]
		}
	}

	err := execTemplate("gdisk.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) AmoPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Amo CRM"}

	user := getJwtUser(r)

	if user != nil {
		amoInfo, err := h.dal.Amo.GetListByUserID(r.Context(), user.UserID)
		if err != nil {
			h.reportError(w, err, 500)
		}

		if amoInfo != nil {
			amoClient, err := h.Amo.NewClient(r.Context(), amoInfo[0].Referer, amoInfo[0].Token(), "")
			if err != nil {
				h.reportError(w, err, 500)
			} else {
				acc, err := amoClient.GetAccount()
				if err != nil {
					h.reportError(w, err, 500)
				}

				fmt.Printf("amoAcc: %+v \r\n", acc)
			}
		}

		if err != nil {
			h.reportError(w, err, 500)
		}
	}

	err := execTemplate("amo.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) LogoutPage(w http.ResponseWriter, r *http.Request) {
	data := map[string]interface{}{"Title": "Logout"}
	err := execTemplate("logout.gohtml", data, w)
	if err != nil {
		h.reportError(w, err, 500)
	}
}

func (h *Handlers) PageNotFound(w http.ResponseWriter, r *http.Request) {
	sendResponse(w, 404, "404 - Page not found / Страница не найдена")
}
