package handlers

import (
	"context"
	"fmt"
	"log"
	"net/http"
	"strings"
	"time"

	"tankstopp/internal/auth"
	"tankstopp/internal/currency"
	"tankstopp/internal/models"
	"tankstopp/internal/views/pages"
)

// RootHandler redirects to appropriate page based on authentication status
func (h *Handler) RootHandler(w http.ResponseWriter, r *http.Request) {
	// Check if user is authenticated
	sessionID, err := auth.GetSessionCookie(r)
	if err != nil {
		http.Redirect(w, r, "/login", http.StatusSeeOther)
		return
	}

	_, exists := h.sessionManager.GetSession(sessionID)
	if !exists {
		http.Redirect(w, r, "/login", http.StatusSeeOther)
		return
	}

	// User is authenticated, redirect to dashboard
	http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
}

// LoginHandler handles user authentication
func (h *Handler) LoginHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		component := pages.LoginPage("")

		w.Header().Set("Content-Type", "text/html")
		err := component.Render(r.Context(), w)
		if err != nil {
			log.Printf("Error rendering template: %v", err)
			http.Error(w, "Internal server error", http.StatusInternalServerError)
		}
	case "POST":
		h.handleLogin(w, r)
	default:
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
	}
}

// handleLogin processes login form submission
func (h *Handler) handleLogin(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		log.Printf("Error parsing form: %v", err)
		h.renderLoginWithError(w, "Invalid form data")
		return
	}

	username := strings.TrimSpace(r.FormValue("username"))
	password := r.FormValue("password")

	if username == "" || password == "" {
		h.renderLoginWithError(w, "Username and password are required")
		return
	}

	// Get user from database
	user, err := h.db.GetUserByUsername(username)
	if err != nil {
		log.Printf("Error getting user: %v", err)
		h.renderLoginWithError(w, "Invalid username or password")
		return
	}

	// Check if user exists
	if user == nil {
		h.renderLoginWithError(w, "Invalid username or password")
		return
	}

	// Check password
	if !user.CheckPassword(password) {
		h.renderLoginWithError(w, "Invalid username or password")
		return
	}

	// Create session
	session := h.sessionManager.CreateSession(int(user.ID), user.Username)

	// Set session cookie
	cookie := &http.Cookie{
		Name:     "session_id",
		Value:    session.ID,
		Path:     "/",
		HttpOnly: true,
		Secure:   false, // Set to true in production with HTTPS
		SameSite: http.SameSiteStrictMode,
		Expires:  session.ExpiresAt,
	}
	http.SetCookie(w, cookie)

	// Redirect to dashboard
	http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
}

// renderLoginWithError renders the login page with an error message
func (h *Handler) renderLoginWithError(w http.ResponseWriter, errorMsg string) {
	component := pages.LoginPage(errorMsg)

	w.Header().Set("Content-Type", "text/html")
	err := component.Render(context.Background(), w)
	if err != nil {
		log.Printf("Error rendering template: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
	}
}

// RegisterHandler handles user registration
func (h *Handler) RegisterHandler(w http.ResponseWriter, r *http.Request) {
	switch r.Method {
	case "GET":
		component := pages.RegisterPage("")

		w.Header().Set("Content-Type", "text/html")
		err := component.Render(r.Context(), w)
		if err != nil {
			log.Printf("Error rendering template: %v", err)
			http.Error(w, "Internal server error", http.StatusInternalServerError)
		}
	case "POST":
		h.handleRegister(w, r)
	default:
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
	}
}

// handleRegister processes registration form submission
func (h *Handler) handleRegister(w http.ResponseWriter, r *http.Request) {
	err := r.ParseForm()
	if err != nil {
		log.Printf("Error parsing form: %v", err)
		h.renderRegisterWithError(w, "Invalid form data")
		return
	}

	// Parse form data
	form := models.UserRegistrationForm{
		Username:        strings.TrimSpace(r.FormValue("username")),
		Email:           strings.TrimSpace(r.FormValue("email")),
		Password:        r.FormValue("password"),
		ConfirmPassword: r.FormValue("confirm_password"),
		BaseCurrency:    r.FormValue("base_currency"),
	}

	// Validate form
	if err := h.validateRegistrationForm(&form); err != nil {
		h.renderRegisterWithError(w, err.Error())
		return
	}

	// Convert form to user
	user, err := form.ToUser()
	if err != nil {
		log.Printf("Error converting form to user: %v", err)
		h.renderRegisterWithError(w, "Failed to create user")
		return
	}

	// Create user in database
	err = h.db.CreateUser(user)
	if err != nil {
		log.Printf("Error creating user: %v", err)
		if strings.Contains(err.Error(), "UNIQUE constraint failed") {
			h.renderRegisterWithError(w, "Username or email already exists")
		} else {
			h.renderRegisterWithError(w, "Failed to create account")
		}
		return
	}

	// Redirect to login with success message
	http.Redirect(w, r, "/login?success=Account+created+successfully", http.StatusSeeOther)
}

// validateRegistrationForm validates the registration form data
func (h *Handler) validateRegistrationForm(form *models.UserRegistrationForm) error {
	if form.Username == "" {
		return fmt.Errorf("Username is required")
	}

	if len(form.Username) < 3 {
		return fmt.Errorf("Username must be at least 3 characters long")
	}

	if form.Email == "" {
		return fmt.Errorf("Email is required")
	}

	if !strings.Contains(form.Email, "@") {
		return fmt.Errorf("Invalid email address")
	}

	if form.Password == "" {
		return fmt.Errorf("Password is required")
	}

	if len(form.Password) < 8 {
		return fmt.Errorf("Password must be at least 8 characters long")
	}

	if form.Password != form.ConfirmPassword {
		return fmt.Errorf("Passwords do not match")
	}

	if form.BaseCurrency == "" {
		return fmt.Errorf("Base currency is required")
	}

	if !currency.IsValidCurrency(form.BaseCurrency) {
		return fmt.Errorf("Invalid currency")
	}

	return nil
}

// renderRegisterWithError renders the registration page with an error message
func (h *Handler) renderRegisterWithError(w http.ResponseWriter, errorMsg string) {
	component := pages.RegisterPage(errorMsg)

	w.Header().Set("Content-Type", "text/html")
	err := component.Render(context.Background(), w)
	if err != nil {
		log.Printf("Error rendering template: %v", err)
		http.Error(w, "Internal server error", http.StatusInternalServerError)
	}
}

// LogoutHandler handles user logout
func (h *Handler) LogoutHandler(w http.ResponseWriter, r *http.Request) {
	if r.Method != "POST" {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// Get session cookie
	sessionID, err := auth.GetSessionCookie(r)
	if err == nil {
		// Remove session from session manager
		h.sessionManager.DeleteSession(sessionID)
	}

	// Clear session cookie
	cookie := &http.Cookie{
		Name:     "session_id",
		Value:    "",
		Path:     "/",
		HttpOnly: true,
		Secure:   false, // Set to true in production with HTTPS
		SameSite: http.SameSiteStrictMode,
		Expires:  time.Unix(0, 0), // Expire immediately
	}
	http.SetCookie(w, cookie)

	// Redirect to login page
	http.Redirect(w, r, "/login", http.StatusSeeOther)
}
