package handlers

import (
	"encoding/json"
	"fmt"
	"furry-sos-backend/config"
	"io"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

// ============================================
// 📝 แจ้งเหตุฉุกเฉิน (รองรับรูป)
// ============================================

func SubmitEmergencyReport(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(
			w,
			"Method not allowed",
			http.StatusMethodNotAllowed,
		)
		return
	}

	// ========================================================
	// อ่าน Multipart Form
	// รองรับข้อมูล + รูปภาพ
	// ========================================================

	err := r.ParseMultipartForm(5 << 20) // 5 MB

	if err != nil {
		http.Error(
			w,
			"Failed to parse form: "+err.Error(),
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ดึงข้อมูลจาก Form
	// ========================================================

	userID := strings.TrimSpace(
		r.FormValue("user_id"),
	)

	animalType := strings.TrimSpace(
		r.FormValue("animal_type"),
	)

	injuryType := strings.TrimSpace(
		r.FormValue("injury_type"),
	)

	injuryDesc := strings.TrimSpace(
		r.FormValue("injury_description"),
	)

	severityLevel := normalizeEmergencySeverity(
		r.FormValue("severity_level"),
	)

	fmt.Println("RECEIVED severity_level =", severityLevel)

	locationLat := strings.TrimSpace(
		r.FormValue("location_lat"),
	)

	locationLng := strings.TrimSpace(
		r.FormValue("location_lng"),
	)
	locationAddr := strings.TrimSpace(
		r.FormValue("location_address"),
	)

	province := strings.TrimSpace(
		r.FormValue("province"),
	)

	isAnonymous := strings.TrimSpace(
		r.FormValue("is_anonymous"),
	)

	// ========================================================
	// DEBUG
	// ========================================================

	fmt.Println("========================================")
	fmt.Println("🚨 EMERGENCY REPORT")
	fmt.Println("user_id =", userID)
	fmt.Println("animal_type =", animalType)
	fmt.Println("injury_type =", injuryType)
	fmt.Println("injury_description =", injuryDesc)
	fmt.Println("severity_level =", severityLevel)
	fmt.Println("location_lat =", locationLat)
	fmt.Println("location_lng =", locationLng)
	fmt.Println("location_address =", locationAddr)
	fmt.Println("province =", province)
	fmt.Println("is_anonymous =", isAnonymous)
	fmt.Println("========================================")

	// ========================================================
	// ตรวจข้อมูลที่จำเป็น
	// ========================================================

	if userID == "" {
		http.Error(
			w,
			"Missing required field: user_id",
			http.StatusBadRequest,
		)
		return
	}

	if animalType == "" {
		http.Error(
			w,
			"Missing required field: animal_type",
			http.StatusBadRequest,
		)
		return
	}

	if injuryType == "" {
		http.Error(
			w,
			"Missing required field: injury_type",
			http.StatusBadRequest,
		)
		return
	}

	if locationLat == "" {
		http.Error(
			w,
			"Missing required field: location_lat",
			http.StatusBadRequest,
		)
		return
	}

	if locationLng == "" {
		http.Error(
			w,
			"Missing required field: location_lng",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ตรวจ User ID เป็นตัวเลข
	// ========================================================

	userIDInt, err := strconv.Atoi(userID)

	if err != nil {
		http.Error(
			w,
			"Invalid user_id",
			http.StatusBadRequest,
		)
		return
	}

	if userIDInt <= 0 {
		http.Error(
			w,
			"Invalid user_id",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ตรวจ Latitude / Longitude
	// ========================================================

	lat, err := strconv.ParseFloat(
		locationLat,
		64,
	)

	if err != nil {
		http.Error(
			w,
			"Invalid location_lat",
			http.StatusBadRequest,
		)
		return
	}

	lng, err := strconv.ParseFloat(
		locationLng,
		64,
	)

	if err != nil {
		http.Error(
			w,
			"Invalid location_lng",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ตรวจช่วงพิกัด
	// ========================================================

	if lat < -90 || lat > 90 {
		http.Error(
			w,
			"Invalid latitude",
			http.StatusBadRequest,
		)
		return
	}

	if lng < -180 || lng > 180 {
		http.Error(
			w,
			"Invalid longitude",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// แปลง is_anonymous
	// ========================================================

	anonymous := false

	if strings.EqualFold(
		isAnonymous,
		"true",
	) ||
		isAnonymous == "1" {
		anonymous = true
	}

	// ========================================================
	// 📸 อัปโหลดรูป
	// ========================================================

	var imageURL string

	file, header, err := r.FormFile("image")

	if err == nil {
		defer file.Close()

		fmt.Println(
			"📸 พบรูป:",
			header.Filename,
		)

		// ----------------------------------------------------
		// สร้าง uploads
		// ----------------------------------------------------

		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
			}
		}

		// ----------------------------------------------------
		// ตั้งชื่อไฟล์
		// ----------------------------------------------------

		fileName := fmt.Sprintf(
			"report_%d_%d.jpg",
			userIDInt,
			time.Now().Unix(),
		)

		filePath := filepath.Join(
			uploadDir,
			fileName,
		)

		// ----------------------------------------------------
		// สร้างไฟล์
		// ----------------------------------------------------

		out, err := os.Create(
			filePath,
		)

		if err != nil {
			http.Error(
				w,
				"Failed to save file: "+
					err.Error(),
				http.StatusInternalServerError,
			)
			return
		}

		// ----------------------------------------------------
		// Copy
		// ----------------------------------------------------

		_, err = io.Copy(
			out,
			file,
		)

		closeErr := out.Close()

		if err != nil {
			http.Error(
				w,
				"Failed to copy file: "+
					err.Error(),
				http.StatusInternalServerError,
			)
			return
		}

		if closeErr != nil {
			http.Error(
				w,
				"Failed to close image file: "+
					closeErr.Error(),
				http.StatusInternalServerError,
			)
			return
		}

		imageURL =
			"/uploads/" + fileName

		fmt.Println(
			"✅ รูปถูกบันทึก:",
			imageURL,
		)

	} else if err != http.ErrMissingFile {
		fmt.Println(
			"⚠️ อ่านรูปไม่ได้:",
			err,
		)
	}

	// ========================================================
	// สร้าง Case Code
	// ========================================================

	caseCode := generateCaseCode()

	// ========================================================
	// บันทึก Emergency Report
	// ========================================================
	query := `
		INSERT INTO emergency_reports
		(
			user_id,
			case_code,
			animal_type,
			injury_type,
			injury_description,
			severity_level,
			location_lat,
			location_lng,
			location_address,
			province,
			image_url,
			is_anonymous,
			status
		)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'pending')
	`

	result, err := config.DB.Exec(
		query,
		userIDInt,
		caseCode,
		animalType,
		injuryType,
		injuryDesc,
		severityLevel,
		lat,
		lng,
		locationAddr,
		province,
		imageURL,
		anonymous,
	)

	if err != nil {
		fmt.Println(
			"❌ INSERT emergency_reports ERROR:",
			err,
		)

		http.Error(
			w,
			"Failed to save report: "+
				err.Error(),
			http.StatusInternalServerError,
		)
		return
	}

	// ========================================================
	// Report ID
	// ========================================================

	reportID, err := result.LastInsertId()

	if err != nil {
		http.Error(
			w,
			"Failed to get report ID: "+
				err.Error(),
			http.StatusInternalServerError,
		)
		return
	}

	// ========================================================
	// สร้าง Tracking
	// ========================================================

	createTrackingTable()

	trackingQuery := `
		INSERT INTO case_tracking
		(
			report_id,
			report_type,
			status,
			status_description,
			status_order,
			is_current,
			created_by
		)
		VALUES
		(
			?,
			'emergency',
			'pending',
			'รอการรับเรื่อง',
			1,
			TRUE,
			'user'
		)
	`

	_, trackingErr := config.DB.Exec(
		trackingQuery,
		reportID,
	)

	if trackingErr != nil {
		fmt.Println(
			"⚠️ CREATE TRACKING ERROR:",
			trackingErr,
		)
	}

	// ========================================================
	// 🔔 สร้าง Notification ให้ Volunteer ที่ได้รับอนุมัติ
	// ========================================================

	createNotificationsTable()

	notificationQuery := `
		INSERT INTO notifications
		(
			user_id,
			title,
			message,
			is_read,
			notification_type,
			reference_id
		)
		SELECT
			v.user_id,
			'🚨 มีเหตุฉุกเฉินใหม่',
			CONCAT(
				'มีเหตุฉุกเฉินใหม่ ',
			?,
				' รอรับงาน กรุณาตรวจสอบรายละเอียด'
			),
			FALSE,
			'system',
			?
		FROM volunteers v
		WHERE v.is_approved = 1
	`

	_, notificationErr := config.DB.Exec(
		notificationQuery,
		caseCode,
		reportID,
	)

	if notificationErr != nil {
		fmt.Println(
			"❌ CREATE EMERGENCY NOTIFICATION ERROR:",
			notificationErr,
		)
	} else {
		fmt.Println(
			"✅ สร้าง Notification เหตุฉุกเฉินให้อาสาสมัครแล้ว",
		)
	}

	// ตรวจสอบว่ามี Notification ถูกสร้างจริงกี่รายการ
	var notificationCount int

	countErr := config.DB.QueryRow(
		`
		SELECT COUNT(*)
		FROM notifications
		WHERE reference_id = ?
		  AND notification_type = 'system'
		`,
		reportID,
	).Scan(&notificationCount)

	if countErr != nil {
		fmt.Println(
			"⚠️ COUNT EMERGENCY NOTIFICATION ERROR:",
			countErr,
		)
	}

	// ========================================================
	// RESPONSE
	// ========================================================

	w.Header().Set(
		"Content-Type",
		"application/json; charset=utf-8",
	)

	w.WriteHeader(
		http.StatusOK,
	)

	json.NewEncoder(w).Encode(
		map[string]interface{}{
			"success":              true,
			"message":              "✅ แจ้งเหตุสำเร็จ!",
			"report_id":            reportID,
			"case_code":            caseCode,
			"status":               "pending",
			"image_url":            imageURL,
			"is_anonymous":         anonymous,
			"notification_created": notificationCount,
		},
	)
}

// ============================================
// 📋 แจ้งซากสัตว์ (รองรับรูป)
// ✅ แก้: รับ severity_level + บันทึก
// ============================================

func SubmitDeceasedReport(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(
			w,
			"Method not allowed",
			http.StatusMethodNotAllowed,
		)
		return
	}

	// ========================================================
	// อ่าน Multipart Form
	// ========================================================

	err := r.ParseMultipartForm(
		5 << 20,
	)

	if err != nil {
		http.Error(
			w,
			"Failed to parse form: "+
				err.Error(),
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ดึงข้อมูล
	// ========================================================

	userID := strings.TrimSpace(
		r.FormValue("user_id"),
	)

	animalType := strings.TrimSpace(
		r.FormValue("animal_type"),
	)

	// ✅ อ่าน severity_level
	severityLevel := strings.TrimSpace(
		r.FormValue("severity_level"),
	)

	if severityLevel == "" {
		severityLevel = "low"
	}

	// normalize
	severityLevel = normalizeEmergencySeverity(severityLevel)

	locationLat := strings.TrimSpace(
		r.FormValue("location_lat"),
	)

	locationLng := strings.TrimSpace(
		r.FormValue("location_lng"),
	)

	locationAddr := strings.TrimSpace(
		r.FormValue("location_address"),
	)

	notes := strings.TrimSpace(
		r.FormValue("notes"),
	)

	// ========================================================
	// DEBUG
	// ========================================================

	fmt.Println("========================================")
	fmt.Println("📋 DECEASED REPORT")
	fmt.Println("user_id =", userID)
	fmt.Println("animal_type =", animalType)
	fmt.Println("severity_level =", severityLevel)
	fmt.Println("location_lat =", locationLat)
	fmt.Println("location_lng =", locationLng)
	fmt.Println("location_address =", locationAddr)
	fmt.Println("notes =", notes)
	fmt.Println("========================================")

	// ========================================================
	// ตรวจข้อมูล
	// ========================================================

	if userID == "" {
		http.Error(
			w,
			"Missing required field: user_id",
			http.StatusBadRequest,
		)
		return
	}

	if animalType == "" {
		http.Error(
			w,
			"Missing required field: animal_type",
			http.StatusBadRequest,
		)
		return
	}

	userIDInt, err := strconv.Atoi(
		userID,
	)

	if err != nil ||
		userIDInt <= 0 {
		http.Error(
			w,
			"Invalid user_id",
			http.StatusBadRequest,
		)
		return
	}

	// ========================================================
	// ตรวจพิกัด ถ้ามี
	// ========================================================

	var lat interface{}
	var lng interface{}

	if locationLat != "" {
		latValue, err := strconv.ParseFloat(
			locationLat,
			64,
		)

		if err != nil {
			http.Error(
				w,
				"Invalid location_lat",
				http.StatusBadRequest,
			)
			return
		}

		lat = latValue
	}

	if locationLng != "" {
		lngValue, err := strconv.ParseFloat(
			locationLng,
			64,
		)

		if err != nil {
			http.Error(
				w,
				"Invalid location_lng",
				http.StatusBadRequest,
			)
			return
		}

		lng = lngValue
	}

	// ========================================================
	// 📸 อัปโหลดรูป
	// ========================================================

	var imageURL string

	file, _, err := r.FormFile(
		"image",
	)

	if err == nil {
		defer file.Close()

		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
			}
		}

		fileName := fmt.Sprintf(
			"deceased_%d_%d.jpg",
			userIDInt,
			time.Now().Unix(),
		)

		filePath := filepath.Join(
			uploadDir,
			fileName,
		)

		out, err := os.Create(
			filePath,
		)

		if err != nil {
			http.Error(
				w,
				"Failed to save file: "+
					err.Error(),
				http.StatusInternalServerError,
			)
			return
		}

		_, err = io.Copy(
			out,
			file,
		)

		closeErr := out.Close()

		if err != nil {
			http.Error(
				w,
				"Failed to copy file: "+
					err.Error(),
				http.StatusInternalServerError,
			)
			return
		}

		if closeErr != nil {
			http.Error(
				w,
				"Failed to close image file: "+
					closeErr.Error(),
				http.StatusInternalServerError,
			)
			return
		}

		imageURL =
			"/uploads/" + fileName

		fmt.Println(
			"✅ รูปซากสัตว์ถูกบันทึก:",
			imageURL,
		)
	}

	// ========================================================
	// INSERT
	// ✅ แก้: เพิ่ม severity_level
	// ========================================================

	query := `
		INSERT INTO deceased_reports
		(
			user_id,
			animal_type,
			location_lat,
			location_lng,
			location_address,
			image_url,
			notes,
			severity_level,
			status
		)
		VALUES (?, ?, ?, ?, ?, ?, ?, ?, 'pending')
	`

	result, err := config.DB.Exec(
		query,
		userIDInt,
		animalType,
		lat,
		lng,
		locationAddr,
		imageURL,
		notes,
		severityLevel, // ✅ เพิ่ม
	)

	if err != nil {
		fmt.Println(
			"❌ INSERT deceased_reports ERROR:",
			err,
		)

		http.Error(
			w,
			"Failed to save report: "+
				err.Error(),
			http.StatusInternalServerError,
		)
		return
	}

	// ========================================================
	// Report ID
	// ========================================================

	reportID, err := result.LastInsertId()

	if err != nil {
		http.Error(
			w,
			"Failed to get report ID: "+
				err.Error(),
			http.StatusInternalServerError,
		)
		return
	}

	// ========================================================
	// Tracking
	// ========================================================

	createTrackingTable()

	trackingQuery := `
		INSERT INTO case_tracking
		(
			report_id,
			report_type,
			status,
			status_description,
			status_order,
			is_current,
			created_by
		)
		VALUES
		(
			?,
			'deceased',
			'pending',
			'รอการรับเรื่อง',
			1,
			TRUE,
			'user'
		)
	`

	_, trackingErr := config.DB.Exec(
		trackingQuery,
		reportID,
	)

	if trackingErr != nil {
		fmt.Println(
			"⚠️ CREATE DECEASED TRACKING ERROR:",
			trackingErr,
		)
	}

	// ========================================================
	// 🔔 สร้าง Notification ให้ Volunteer ที่ได้รับอนุมัติ
	// ========================================================

	createNotificationsTable()

	notificationQuery := `
		INSERT INTO notifications
		(
			user_id,
			title,
			message,
			is_read,
			notification_type,
			reference_id
		)
		SELECT
			v.user_id,
			'📋 มีงานจัดการซากสัตว์ใหม่',
			CONCAT(
				'มีงานจัดการซากสัตว์ใหม่ ',
				'BR-',
				LPAD(?, 4, '0'),
				' รอรับงาน'
			),
			FALSE,
			'system',
			?
		FROM volunteers v
		WHERE v.is_approved = 1
	`

	_, notificationErr := config.DB.Exec(
		notificationQuery,
		reportID,
		reportID,
	)

	if notificationErr != nil {
		fmt.Println(
			"❌ CREATE DECEASED NOTIFICATION ERROR:",
			notificationErr,
		)
	} else {
		fmt.Println(
			"✅ สร้าง Notification งานจัดการซากสัตว์แล้ว",
		)
	}

	// ตรวจสอบว่ามี Notification ถูกสร้างจริงกี่รายการ
	var notificationCount int

	countErr := config.DB.QueryRow(
		`
		SELECT COUNT(*)
		FROM notifications
		WHERE reference_id = ?
		  AND notification_type = 'system'
		`,
		reportID,
	).Scan(&notificationCount)

	if countErr != nil {
		fmt.Println(
			"⚠️ COUNT DECEASED NOTIFICATION ERROR:",
			countErr,
		)
	}

	// ========================================================
	// RESPONSE
	// ========================================================

	w.Header().Set(
		"Content-Type",
		"application/json; charset=utf-8",
	)

	w.WriteHeader(
		http.StatusOK,
	)

	json.NewEncoder(w).Encode(
		map[string]interface{}{
			"success":              true,
			"message":              "✅ แจ้งซากสัตว์สำเร็จ!",
			"report_id":            reportID,
			"status":               "pending",
			"image_url":            imageURL,
			"notification_created": notificationCount,
		},
	)
}

// ============================================
// 🔧 สร้าง Case Code
// ============================================

func generateCaseCode() string {
	now := time.Now()

	dateStr := now.Format(
		"20060102",
	)

	var count int

	err := config.DB.QueryRow(
		`
		SELECT COUNT(*)
		FROM emergency_reports
		WHERE DATE(created_at) = CURDATE()
		`,
	).Scan(&count)

	if err != nil {
		fmt.Println(
			"⚠️ generateCaseCode ERROR:",
			err,
		)
	}

	return fmt.Sprintf(
		"SOS-%s-%04d",
		dateStr,
		count+1,
	)
}

// ============================================
// 🔧 สร้าง Tracking Table
// ============================================

func createTrackingTable() {
	query := `
		CREATE TABLE IF NOT EXISTS case_tracking
		(
			tracking_id INT PRIMARY KEY AUTO_INCREMENT,

			report_id INT NOT NULL,

			report_type
				ENUM(
					'emergency',
					'deceased'
				)
				NOT NULL,

			status VARCHAR(50) NOT NULL,

			status_description TEXT,

			status_order INT DEFAULT 0,

			is_current BOOLEAN DEFAULT FALSE,

			created_by
				ENUM(
					'system',
					'user',
					'volunteer',
					'admin'
				)
				DEFAULT 'system',

			created_at
				TIMESTAMP DEFAULT CURRENT_TIMESTAMP
		)
	`

	_, err := config.DB.Exec(query)

	if err != nil {
		fmt.Println(
			"⚠️ createTrackingTable ERROR:",
			err,
		)
	}
}

// normalizeEmergencySeverity converts English keys and Thai labels to
// the canonical values stored in emergency_reports.
func normalizeEmergencySeverity(value string) string {
	value = strings.ToLower(strings.TrimSpace(value))

	switch value {
	case "critical", "emergency", "ด่วนมาก", "เร่งด่วนมาก", "วิกฤต":
		return "critical"
	case "high", "severe", "urgent", "สูง", "ด่วน", "เร่งด่วน", "รุนแรง":
		return "high"
	case "medium", "moderate", "ปานกลาง":
		return "medium"
	case "low", "normal", "ต่ำ", "ปกติ", "เล็กน้อย":
		return "low"
	default:
		// Avoid promoting an unknown input to critical.
		return "medium"
	}
}