package handlers

import (
	"database/sql" // ✅ เพิ่ม import นี้
	"encoding/json"
	"fmt"
	"furry-sos-backend/config"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"time"
)

type UpdateProfileRequest struct {
	UserID       int    `json:"user_id"`
	FullName     string `json:"full_name"`
	Email        string `json:"email"`
	Phone        string `json:"phone"`
	ProfileImage string `json:"profile_image"`
	Password     string `json:"password,omitempty"`
}

// ============================================================
// GET USER PROFILE
// GET /api/profile
// Header:
// X-User-ID: 3
// ============================================================

func GetUserProfile(w http.ResponseWriter, r *http.Request) {

	if r.Method != http.MethodGet {
		http.Error(
			w,
			"Method not allowed",
			http.StatusMethodNotAllowed,
		)
		return
	}

	// ========================================================
	// รับ user_id จาก X-User-ID ก่อน
	// ========================================================

	userID := r.Header.Get("X-User-ID")

	// รองรับแบบเก่าด้วย ?user_id=3
	if userID == "" {
		userID = r.URL.Query().Get("user_id")
	}

	if userID == "" {
		http.Error(
			w,
			"Missing user_id",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ตรวจสอบว่า user_id เป็นตัวเลข
	// ========================================================

	userIDInt, err := strconv.Atoi(userID)

	if err != nil || userIDInt <= 0 {
		http.Error(
			w,
			"Invalid user_id",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// DEBUG
	// ========================================================

	fmt.Println("======================================")
	fmt.Println("👤 GET USER PROFILE")
	fmt.Println("user_id =", userIDInt)
	fmt.Println("======================================")

	// ========================================================
	// QUERY DATABASE - ใช้ sql.NullString สำหรับ NULL
	// ========================================================

	var username string
	var fullName string
	var email string
	var phone string
	var profileImage sql.NullString // ✅ เปลี่ยนเป็น sql.NullString
	var role string
	var isVerified bool
	var createdAt string

	query := `
		SELECT
			username,
			full_name,
			email,
			phone,
			profile_image,
			is_verified,
			role,
			created_at
		FROM users
		WHERE user_id = ?
	`

	err = config.DB.QueryRow(
		query,
		userIDInt,
	).Scan(
		&username,
		&fullName,
		&email,
		&phone,
		&profileImage, // ✅ รับค่า NULL ได้
		&isVerified,
		&role,
		&createdAt,
	)

	if err != nil {

		fmt.Println("❌ Get profile error:", err)

		http.Error(
			w,
			"User not found",
			http.StatusNotFound,
		)

		return
	}

	// ========================================================
	// RESPONSE - ตรวจสอบ NULL
	// ========================================================

	w.Header().Set(
		"Content-Type",
		"application/json",
	)

	json.NewEncoder(w).Encode(
		map[string]interface{}{
			"user_id":       userIDInt,
			"username":      username,
			"full_name":     fullName,
			"email":         email,
			"phone":         phone,
			"profile_image": profileImage.String, // ✅ ถ้า NULL จะได้ ""
			"is_verified":   isVerified,
			"role":          role,
			"created_at":    createdAt,
		},
	)
}

// ============================================================
// UPDATE USER PROFILE
// POST /api/profile/update
//
// Header:
// X-User-ID: 3
// ============================================================

func UpdateUserProfile(
	w http.ResponseWriter,
	r *http.Request,
) {

	if r.Method != http.MethodPost &&
		r.Method != http.MethodPut {

		http.Error(
			w,
			"Method not allowed",
			http.StatusMethodNotAllowed,
		)

		return
	}

	// ========================================================
	// อ่าน JSON
	// ========================================================

	var req UpdateProfileRequest

	err := json.NewDecoder(
		r.Body,
	).Decode(&req)

	if err != nil {

		http.Error(
			w,
			"Invalid JSON: "+err.Error(),
			http.StatusBadRequest,
		)

		return
	}

	// ========================================================
	// ถ้า body ไม่มี user_id
	// ให้ใช้ X-User-ID
	// ========================================================

	if req.UserID <= 0 {

		headerUserID := r.Header.Get("X-User-ID")

		if headerUserID != "" {

			id, err := strconv.Atoi(headerUserID)

			if err == nil {
				req.UserID = id
			}
		}
	}

	// ========================================================
	// ตรวจสอบ user_id
	// ========================================================

	if req.UserID <= 0 {

		http.Error(
			w,
			"Missing user_id",
			http.StatusBadRequest,
		)

		return
	}

	// ========================================================
	// DEBUG
	// ========================================================

	fmt.Println("======================================")
	fmt.Println("✏️ UPDATE USER PROFILE")
	fmt.Println("user_id =", req.UserID)
	fmt.Println("full_name =", req.FullName)
	fmt.Println("email =", req.Email)
	fmt.Println("phone =", req.Phone)
	fmt.Println("======================================")

	// ========================================================
	// ตรวจสอบว่ามี User
	// ========================================================

	var exists bool

	checkQuery := `
		SELECT EXISTS(
			SELECT 1
			FROM users
			WHERE user_id = ?
		)
	`

	err = config.DB.QueryRow(
		checkQuery,
		req.UserID,
	).Scan(&exists)

	if err != nil {

		http.Error(
			w,
			"Database error: "+err.Error(),
			http.StatusInternalServerError,
		)

		return
	}

	if !exists {

		http.Error(
			w,
			fmt.Sprintf(
				"User with ID %d not found",
				req.UserID,
			),
			http.StatusNotFound,
		)

		return
	}

	// ========================================================
	// UPDATE
	// ========================================================

	profileImage := req.ProfileImage

	var query string
	var args []interface{}

	if req.Password != "" &&
		len(req.Password) >= 6 {

		query = `
			UPDATE users
			SET
				full_name = ?,
				email = ?,
				phone = ?,
				profile_image = ?,
				password_hash = ?,
				updated_at = NOW()
			WHERE user_id = ?
		`

		args = []interface{}{
			req.FullName,
			req.Email,
			req.Phone,
			profileImage,
			req.Password,
			req.UserID,
		}

	} else {

		query = `
			UPDATE users
			SET
				full_name = ?,
				email = ?,
				phone = ?,
				profile_image = ?,
				updated_at = NOW()
			WHERE user_id = ?
		`

		args = []interface{}{
			req.FullName,
			req.Email,
			req.Phone,
			profileImage,
			req.UserID,
		}
	}

	result, err := config.DB.Exec(
		query,
		args...,
	)

	if err != nil {

		http.Error(
			w,
			"Database error: "+err.Error(),
			http.StatusInternalServerError,
		)

		return
	}

	rowsAffected, _ := result.RowsAffected()

	// ========================================================
	// RESPONSE
	// ========================================================

	w.Header().Set(
		"Content-Type",
		"application/json",
	)

	json.NewEncoder(w).Encode(
		map[string]interface{}{
			"message":       "✅ อัปเดตข้อมูลสำเร็จ!",
			"user_id":       req.UserID,
			"rows_affected": rowsAffected,
		},
	)
}

// ============================================================
// UPLOAD PROFILE IMAGE
// POST /api/profile/upload-image
//
// Header:
// X-User-ID: 3
//
// File:
// file
// ============================================================

func UploadProfileImage(
	w http.ResponseWriter,
	r *http.Request,
) {

	if r.Method != http.MethodPost {

		http.Error(
			w,
			"Method not allowed",
			http.StatusMethodNotAllowed,
		)

		return
	}

	// ========================================================
	// รับ user_id จาก Header
	// ========================================================

	userID := r.Header.Get("X-User-ID")

	// รองรับ Form ด้วย
	if userID == "" {
		userID = r.FormValue("user_id")
	}

	if userID == "" {

		http.Error(
			w,
			"Missing user_id",
			http.StatusBadRequest,
		)

		return
	}

	userIDInt, err := strconv.Atoi(userID)

	if err != nil || userIDInt <= 0 {

		http.Error(
			w,
			"Invalid user_id",
			http.StatusBadRequest,
		)

		return
	}

	// ========================================================
	// DEBUG
	// ========================================================

	fmt.Println("======================================")
	fmt.Println("📸 UPLOAD PROFILE IMAGE")
	fmt.Println("user_id =", userIDInt)
	fmt.Println("======================================")

	// ========================================================
	// Multipart
	// ========================================================

	err = r.ParseMultipartForm(
		5 << 20,
	)

	if err != nil {

		http.Error(
			w,
			"Failed to parse form: "+err.Error(),
			http.StatusBadRequest,
		)

		return
	}

	// ========================================================
	// Flutter ส่งชื่อ field = file
	// ========================================================

	file, _, err := r.FormFile("file")

	// รองรับชื่อเก่าด้วย image
	if err != nil {

		file, _, err = r.FormFile("image")
	}

	if err != nil {

		http.Error(
			w,
			"Failed to get image: "+err.Error(),
			http.StatusBadRequest,
		)

		return
	}

	defer file.Close()

	// ========================================================
	// File name
	// ========================================================

	fileName := fmt.Sprintf(
		"profile_%d_%d.jpg",
		userIDInt,
		time.Now().Unix(),
	)

	uploadDir := "./uploads"

	if _, err := os.Stat(uploadDir); os.IsNotExist(err) {

		err := os.MkdirAll(
			uploadDir,
			0755,
		)

		if err != nil {

			http.Error(
				w,
				"Failed to create upload directory: "+err.Error(),
				http.StatusInternalServerError,
			)

			return
		}
	}

	filePath := filepath.Join(
		uploadDir,
		fileName,
	)

	out, err := os.Create(filePath)

	if err != nil {

		http.Error(
			w,
			"Failed to create file: "+err.Error(),
			http.StatusInternalServerError,
		)

		return
	}

	defer out.Close()

	_, err = io.Copy(
		out,
		file,
	)

	if err != nil {

		http.Error(
			w,
			"Failed to save file: "+err.Error(),
			http.StatusInternalServerError,
		)

		return
	}

	// ========================================================
	// Save image URL
	// ========================================================

	imageURL := "/uploads/" + fileName

	query := `
		UPDATE users
		SET
			profile_image = ?,
			updated_at = NOW()
		WHERE user_id = ?
	`

	_, err = config.DB.Exec(
		query,
		imageURL,
		userIDInt,
	)

	if err != nil {

		http.Error(
			w,
			"Failed to update profile image: "+err.Error(),
			http.StatusInternalServerError,
		)

		return
	}

	// ========================================================
	// RESPONSE
	// ========================================================

	w.Header().Set(
		"Content-Type",
		"application/json",
	)

	json.NewEncoder(w).Encode(
		map[string]interface{}{
			"message":   "✅ อัปโหลดรูปสำเร็จ!",
			"image_url": imageURL,
			"user_id":   userIDInt,
		},
	)
}
