package main

import (
	"log"
	"net/http"
	"os"

	"furry-sos-backend/config"
	"furry-sos-backend/handlers"
)

// ======================================================
// CORS MIDDLEWARE
// ======================================================

func corsMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

		w.Header().Set(
			"Access-Control-Allow-Origin",
			"*",
		)

		w.Header().Set(
			"Access-Control-Allow-Methods",
			"GET, POST, PUT, DELETE, OPTIONS",
		)

		w.Header().Set(
			"Access-Control-Allow-Headers",
			"Content-Type, Accept, X-User-ID, Authorization",
		)

		if r.Method == http.MethodOptions {
			w.WriteHeader(http.StatusOK)
			return
		}

		next.ServeHTTP(w, r)
	})
}

// ======================================================
// MAIN
// ======================================================

func main() {

	// ==================================================
	// LOAD ENV
	// ==================================================

	config.LoadEnv()

	maxPlusKey := os.Getenv("MAXPLUS_API_KEY")

	if maxPlusKey == "" {
		log.Println("??  MAXPLUS_API_KEY = MISSING")
	} else {
		log.Println("? MAXPLUS_API_KEY = OK")
	}

	// ==================================================
	// PORT
	// ==================================================

	port := os.Getenv("PORT")

	if port == "" {
		port = "8080"
	}

	// ==================================================
	// DATABASE
	// ==================================================

	config.InitDB()

	log.Println("============================================")
	log.Println("Furry SOS Backend")
	log.Println("============================================")
	log.Println("Database connected")
	log.Println("PORT =", port)

	// ==================================================
	// AUTH
	// ==================================================

	http.HandleFunc(
		"/api/register",
		handlers.Register,
	)

	http.HandleFunc(
		"/api/login",
		handlers.Login,
	)

	http.HandleFunc(
		"/api/forgot-password",
		handlers.ForgotPassword,
	)

	http.HandleFunc(
		"/api/reset-password",
		handlers.ResetPassword,
	)

	// ==================================================
	// PROFILE
	// ==================================================

	http.HandleFunc(
		"/api/profile",
		handlers.GetUserProfile,
	)

	http.HandleFunc(
		"/api/profile/update",
		handlers.UpdateUserProfile,
	)

	http.HandleFunc(
		"/api/profile/upload-image",
		handlers.UploadProfileImage,
	)

	// ==================================================
	// SOS
	// ==================================================

	http.HandleFunc(
		"/api/sos",
		handlers.SOSHandler,
	)

	// ==================================================
	// AI CHAT
	// ==================================================

	http.HandleFunc(
		"/api/chat",
		handlers.ChatHandler,
	)

	// ==================================================
	// CHAT (User <-> Volunteer)
	// ==================================================

	http.HandleFunc("/api/chat/send", handlers.SendChatMessage)
	http.HandleFunc("/api/chat/messages", handlers.GetChatMessages)
	http.HandleFunc("/api/chat/read", handlers.MarkChatAsRead)
	http.HandleFunc("/api/chat/summary", handlers.GetChatSummary)

	// ==================================================
	// GET REPORTER INFO
	// ==================================================

	http.HandleFunc("/api/report/reporter", handlers.GetReportReporter)

	// ==================================================
	// HOSPITAL
	// ==================================================

	http.HandleFunc(
		"/api/hospitals",
		handlers.GetHospitals,
	)

	http.HandleFunc(
		"/api/hospital/review",
		handlers.SubmitHospitalReview,
	)

	http.HandleFunc(
		"/api/hospital/reviews",
		handlers.GetHospitalReviews,
	)

	http.HandleFunc(
		"/api/hospital/rating",
		handlers.GetHospitalRatingSummary,
	)

	http.HandleFunc(
		"/api/user/stats",
		handlers.GetUserStats,
	)

	// ==================================================
	// REPORT
	// ==================================================

	http.HandleFunc(
		"/api/report/emergency",
		handlers.SubmitEmergencyReport,
	)

	http.HandleFunc(
		"/api/report/deceased",
		handlers.SubmitDeceasedReport,
	)

	// ==================================================
	// HISTORY
	// ==================================================

	http.HandleFunc(
		"/api/reports",
		handlers.GetUserReports,
	)

	// ==================================================
	// TRACKING
	// ==================================================

	http.HandleFunc(
		"/api/tracking",
		handlers.GetCaseTracking,
	)

	// ==================================================
	// SHARE
	// ==================================================

	http.HandleFunc(
		"/api/share",
		handlers.ShareCase,
	)

	// ==================================================
	// ADMIN
	// ==================================================

	http.HandleFunc(
		"/api/admin/pending-fundraising",
		handlers.GetPendingFundraising,
	)

	http.HandleFunc(
		"/api/admin/approve-fundraising",
		handlers.ApproveFundraising,
	)

	http.HandleFunc(
		"/api/admin/reject-fundraising",
		handlers.RejectFundraising,
	)

	http.HandleFunc(
		"/api/admin/stats",
		handlers.GetAdminStats,
	)

	http.HandleFunc(
		"/api/admin/check-approval",
		handlers.CheckFundraisingApproval,
	)

	// ==================================================
	// ADMIN / VOLUNTEER
	// ==================================================

	http.HandleFunc(
		"/api/admin/volunteers",
		handlers.GetPendingVolunteers,
	)

	http.HandleFunc(
		"/api/admin/volunteers/approve",
		handlers.ApproveVolunteer,
	)

	http.HandleFunc(
		"/api/admin/volunteers/reject",
		handlers.RejectVolunteer,
	)

	// ==================================================
	// ADMIN / VOLUNTEER TRAINING
	// ==================================================

	http.HandleFunc(
		"/api/admin/volunteer-training/pending",
		handlers.AdminGetPendingVolunteerTraining,
	)

	http.HandleFunc(
		"/api/admin/volunteer-training/approve",
		handlers.AdminApproveVolunteerTraining,
	)

	http.HandleFunc(
		"/api/admin/volunteer-training/reject",
		handlers.AdminRejectVolunteerTraining,
	)

	// ==================================================
	// ADMIN / DASHBOARD STATS
	// ==================================================

	http.HandleFunc(
		"/api/admin/dashboard-stats",
		handlers.GetDashboardStats,
	)

	http.HandleFunc(
		"/api/admin/dashboard-overview",
		handlers.GetAdminDashboardOverview,
	)

	// ==================================================
	// ADMIN / SOS CASES
	// ==================================================

	http.HandleFunc(
		"/api/admin/sos-cases",
		handlers.GetAdminSOSCases,
	)

	http.HandleFunc(
		"/api/admin/sos-cases/detail",
		handlers.GetAdminSOSCaseDetail,
	)

	// ==================================================
	// ADMIN / USERS
	// ==================================================

	http.HandleFunc(
		"/api/admin/users",
		handlers.GetAdminUsers,
	)

	http.HandleFunc(
		"/api/admin/users/history",
		handlers.GetAdminUserHistory,
	)

	// ==================================================
	// ADMIN / REPORTS
	// ==================================================

	http.HandleFunc(
		"/api/admin/reports",
		handlers.GetAdminReports,
	)

	http.HandleFunc(
		"/api/admin/performance",
		handlers.GetAdminPerformance,
	)

	// ==================================================
	// ADMIN / HOSPITAL CRUD
	// ==================================================

	http.HandleFunc(
		"/api/admin/hospitals",
		handlers.AdminHospitalCRUD,
	)

	// ==================================================
	// SYSTEM
	// ==================================================

	http.HandleFunc(
		"/api/system/bank-account",
		handlers.GetSystemBankAccount,
	)

	// ==================================================
	// NOTIFICATIONS
	// ==================================================

	http.HandleFunc(
		"/api/notifications",
		handlers.GetUserNotifications,
	)

	http.HandleFunc(
		"/api/notifications/read",
		handlers.MarkNotificationRead,
	)

	// ==================================================
	// REVIEW
	// ==================================================

	http.HandleFunc(
		"/api/review/submit",
		handlers.SubmitReview,
	)

	http.HandleFunc(
		"/api/review/check",
		handlers.CheckReviewStatus,
	)

	http.HandleFunc(
		"/api/review/get",
		handlers.GetReviewByAssignment,
	)

	// ==================================================
	// VOLUNTEER
	// ==================================================

	http.HandleFunc(
		"/api/volunteer/register",
		handlers.RegisterVolunteer,
	)

	http.HandleFunc(
		"/api/volunteer/status",
		handlers.GetVolunteerStatus,
	)

	http.HandleFunc(
		"/api/volunteer/history",
		handlers.GetVolunteerHistory,
	)

	http.HandleFunc(
		"/api/volunteer/toggle-online",
		handlers.ToggleOnlineStatus,
	)

	http.HandleFunc(
		"/api/volunteer/cases",
		handlers.GetVolunteerCases,
	)

	http.HandleFunc(
		"/api/volunteer/latest-task",
		handlers.GetVolunteerLatestTask,
	)

	http.HandleFunc(
		"/api/volunteer/deceased-cases",
		handlers.GetVolunteerDeceasedCases,
	)

	http.HandleFunc(
		"/api/volunteer/cases/accept",
		handlers.AcceptVolunteerCase,
	)

	http.HandleFunc(
		"/api/volunteer/cases/update-status",
		handlers.UpdateVolunteerCaseStatus,
	)

	http.HandleFunc(
		"/api/volunteer/body-retrieval",
		handlers.GetVolunteerBodyRetrieval,
	)

	http.HandleFunc(
		"/api/volunteer/body-retrieval/accept",
		handlers.AcceptVolunteerBodyRetrieval,
	)

	http.HandleFunc(
		"/api/volunteer/body-retrieval/update-status",
		handlers.UpdateVolunteerBodyRetrievalStatus,
	)

	http.HandleFunc(
		"/api/volunteer/body-retrieval/complete",
		handlers.CompleteVolunteerBodyRetrieval,
	)

	// ==================================================
	// VOLUNTEER TRAINING
	// ==================================================

	http.HandleFunc(
		"/api/volunteer/training",
		handlers.GetVolunteerTraining,
	)

	http.HandleFunc(
		"/api/volunteer/training/submit",
		handlers.SubmitVolunteerTraining,
	)

	// ==================================================
	// UPLOADS (Static files)
	// ==================================================

	fs := http.FileServer(
		http.Dir("./uploads"),
	)

	http.Handle(
		"/uploads/",
		http.StripPrefix(
			"/uploads/",
			fs,
		),
	)

	// ==================================================
	// START SERVER
	// ==================================================

	log.Println("============================================")
	log.Println("Furry SOS Backend Started")
	log.Println("http://localhost:" + port)
	log.Println("============================================")

	log.Println("API Endpoints")
	log.Println("--------------------------------------------")

	// --------------------------------------------------
	// AUTH
	// --------------------------------------------------

	log.Println("Auth")
	log.Println("POST /api/register")
	log.Println("POST /api/login")
	log.Println("POST /api/forgot-password")
	log.Println("POST /api/reset-password")

	// --------------------------------------------------
	// PROFILE
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Profile")
	log.Println("GET  /api/profile")
	log.Println("POST /api/profile/update")
	log.Println("POST /api/profile/upload-image")

	// --------------------------------------------------
	// SOS
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("SOS")
	log.Println("POST /api/sos")

	// --------------------------------------------------
	// AI CHAT
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("AI Chat")
	log.Println("POST /api/chat")

	// --------------------------------------------------
	// CHAT
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Chat")
	log.Println("POST /api/chat/send")
	log.Println("GET  /api/chat/messages")
	log.Println("POST /api/chat/read")
	log.Println("GET  /api/chat/summary")
	log.Println("GET  /api/report/reporter")

	// --------------------------------------------------
	// HOSPITAL
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Hospital")
	log.Println("GET /api/hospitals")

	// --------------------------------------------------
	// REPORT
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Report")
	log.Println("POST /api/report/emergency")
	log.Println("POST /api/report/deceased")

	// --------------------------------------------------
	// HISTORY
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("History")
	log.Println("GET /api/reports")

	// --------------------------------------------------
	// TRACKING
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Tracking")
	log.Println("GET /api/tracking")

	// --------------------------------------------------
	// SHARE
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Share")
	log.Println("POST /api/share")

	// --------------------------------------------------
	// ADMIN
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Admin")
	log.Println("GET  /api/admin/pending-fundraising")
	log.Println("POST /api/admin/approve-fundraising")
	log.Println("POST /api/admin/reject-fundraising")
	log.Println("GET  /api/admin/stats")
	log.Println("GET  /api/admin/check-approval")

	// --------------------------------------------------
	// ADMIN VOLUNTEER
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Admin Volunteer")
	log.Println("GET  /api/admin/volunteers")
	log.Println("POST /api/admin/volunteers/approve")
	log.Println("POST /api/admin/volunteers/reject")

	// --------------------------------------------------
	// ADMIN VOLUNTEER TRAINING
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Admin Volunteer Training")
	log.Println("GET  /api/admin/volunteer-training/pending")
	log.Println("POST /api/admin/volunteer-training/approve")
	log.Println("POST /api/admin/volunteer-training/reject")

	// --------------------------------------------------
	// SYSTEM
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("System")
	log.Println("GET /api/system/bank-account")

	// --------------------------------------------------
	// NOTIFICATIONS
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Notifications")
	log.Println("GET  /api/notifications")
	log.Println("POST /api/notifications/read")

	// --------------------------------------------------
	// REVIEW
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Review")
	log.Println("POST /api/review/submit")
	log.Println("GET  /api/review/check")
	log.Println("GET  /api/review/get")

	// --------------------------------------------------
	// VOLUNTEER
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Volunteer")
	log.Println("POST /api/volunteer/register")
	log.Println("GET  /api/volunteer/status")
	log.Println("POST /api/volunteer/toggle-online")
	log.Println("GET  /api/volunteer/cases")
	log.Println("GET  /api/volunteer/latest-task")
	log.Println("POST /api/volunteer/cases/accept")
	log.Println("POST /api/volunteer/cases/update-status")
	log.Println("GET  /api/volunteer/body-retrieval")
	log.Println("POST /api/volunteer/body-retrieval/accept")
	log.Println("POST /api/volunteer/body-retrieval/complete")

	// --------------------------------------------------
	// VOLUNTEER TRAINING
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Volunteer Training")
	log.Println("GET  /api/volunteer/training")
	log.Println("POST /api/volunteer/training/submit")

	// --------------------------------------------------
	// UPLOADS
	// --------------------------------------------------

	log.Println("--------------------------------------------")
	log.Println("Uploads")
	log.Println("GET /uploads/...")

	log.Println("============================================")

	// ==================================================
	// START SERVER + CORS
	// ==================================================

	handler := corsMiddleware(
		http.DefaultServeMux,
	)

	log.Fatal(
		http.ListenAndServe(
			":"+port,
			handler,
		),
	)
}
