package handlers

import (
	"database/sql"
	"html/template"
	"log"
	"net/http"
	"strconv"

	ory "github.com/ory/client-go"

	"decor-by-hannahs/internal/db"
)

type AdminBooking struct {
	ID            int64
	UserEmail     string
	ServiceName   string
	ServiceOption string
	EventType     string
	EventDate     string
	Address       string
	Notes         string
	Status        string
	CreatedAt     string
}

type AdminData struct {
	ActivePage    string
	Authenticated bool
	OryLoginURL   string
	Bookings      []AdminBooking
}

func AdminHandler(q *db.Queries, tmpl *template.Template, oryClient *ory.APIClient) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		data := AdminData{
			ActivePage:    "admin",
			Authenticated: isAuthenticated(r, oryClient),
			OryLoginURL:   "/login",
		}

		bookings, err := q.ListAllBookingsWithDetails(r.Context())
		if err != nil {
			log.Printf("Error fetching bookings: %v", err)
		} else {
			for _, b := range bookings {
				data.Bookings = append(data.Bookings, AdminBooking{
					ID:            b.ID,
					UserEmail:     b.UserEmail,
					ServiceName:   b.ServiceName,
					ServiceOption: nullStringToString(b.ServiceOption),
					EventType:     nullStringToString(b.EventType),
					EventDate:     b.EventDate.Format("January 2, 2006"),
					Address:       nullStringToString(b.Address),
					Notes:         nullStringToString(b.Notes),
					Status:        nullStringToString(b.Status),
					CreatedAt:     b.CreatedAt.Time.Format("Jan 2, 2006 3:04 PM"),
				})
			}
		}

		if err := tmpl.ExecuteTemplate(w, "admin.tmpl", data); err != nil {
			log.Printf("Error rendering admin template: %v", err)
			http.Error(w, "Failed to render page", http.StatusInternalServerError)
			return
		}
	}
}

func AdminUpdateBookingHandler(q *db.Queries, oryClient *ory.APIClient) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if r.Method != http.MethodPost {
			http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
			return
		}

		bookingID, err := strconv.ParseInt(r.FormValue("booking_id"), 10, 64)
		if err != nil {
			http.Error(w, "Invalid booking ID", http.StatusBadRequest)
			return
		}

		status := r.FormValue("status")
		if status == "" {
			http.Error(w, "Status is required", http.StatusBadRequest)
			return
		}

		err = q.UpdateBookingStatus(r.Context(), db.UpdateBookingStatusParams{
			ID:     bookingID,
			Status: sql.NullString{String: status, Valid: true},
		})
		if err != nil {
			log.Printf("Error updating booking: %v", err)
			http.Error(w, "Failed to update booking", http.StatusInternalServerError)
			return
		}

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