// internal/handler/chat_handler.go
package handler

import (
	"encoding/json"
	"log"
	"net/http"
	"websocket-server/internal/model"
	"websocket-server/internal/service"
	"websocket-server/pkg/websocket"

	gorilla_ws "github.com/gorilla/websocket"
)

type ChatHandler struct {
	chatService *service.ChatService
	chatHub     *websocket.ChatHub
	upgrader    gorilla_ws.Upgrader
}

func NewChatHandler(chatService *service.ChatService, chatHub *websocket.ChatHub) *ChatHandler {
	return &ChatHandler{
		chatService: chatService,
		chatHub:     chatHub,
		upgrader: gorilla_ws.Upgrader{
			ReadBufferSize:  1024,
			WriteBufferSize: 1024,
			CheckOrigin: func(r *http.Request) bool {
				return true // در production باید محدود شود
			},
		},
	}
}

// HandleWebSocket handles WebSocket connections for chat
func (h *ChatHandler) HandleWebSocket(w http.ResponseWriter, r *http.Request) {
	customerID := r.URL.Query().Get("customer_id")
	if customerID == "" {
		http.Error(w, "customer_id is required", http.StatusBadRequest)
		return
	}

	conn, err := h.upgrader.Upgrade(w, r, nil)
	if err != nil {
		log.Printf("WebSocket upgrade error: %v", err)
		return
	}

	client := &websocket.ChatClient{
		Hub:        h.chatHub,
		Conn:       conn,
		Send:       make(chan []byte, 256),
		CustomerID: customerID,
		Service:    h.chatService,
	}

	h.chatHub.Register <- client

	go client.WritePump()
	go client.ReadPump()
}

func (h *ChatHandler) SendMessage(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	// دریافت sender_id از query parameter یا header
	senderID := r.URL.Query().Get("sender_id")
	if senderID == "" {
		http.Error(w, "sender_id is required", http.StatusBadRequest)
		return
	}

	var req model.ChatMessageRequest
	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
		http.Error(w, "invalid request body", http.StatusBadRequest)
		return
	}

	// ارسال پیام
	msg, err := h.chatService.SendMessage(r.Context(), senderID, &req)
	if err != nil {
		log.Printf("Error sending message: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	// ارسال به گیرنده از طریق WebSocket
	response := model.ChatMessageResponse{
		Type:    "new_message",
		Message: msg,
	}
	responseData, _ := json.Marshal(response)
	h.chatHub.SendToUser(req.ReceiverID, responseData)

	// پاسخ به فرستنده
	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(msg)
}

// GetHistory handles fetching message history
func (h *ChatHandler) GetHistory(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	customerID := r.URL.Query().Get("customer_id")
	otherCustomerID := r.URL.Query().Get("other_customer_id")

	if customerID == "" || otherCustomerID == "" {
		http.Error(w, "customer_id and other_customer_id are required", http.StatusBadRequest)
		return
	}

	limit := 50
	offset := 0

	messages, err := h.chatService.GetMessageHistory(r.Context(), customerID, otherCustomerID, limit, offset)
	if err != nil {
		log.Printf("Error getting history: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(messages)
}

// MarkAsRead handles marking messages as read
func (h *ChatHandler) MarkAsRead(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodPost {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	receiverID := r.URL.Query().Get("receiver_id")
	senderID := r.URL.Query().Get("sender_id")

	if receiverID == "" || senderID == "" {
		http.Error(w, "receiver_id and sender_id are required", http.StatusBadRequest)
		return
	}

	err := h.chatService.MarkAsRead(r.Context(), receiverID, senderID)
	if err != nil {
		log.Printf("Error marking as read: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.WriteHeader(http.StatusOK)
	json.NewEncoder(w).Encode(map[string]string{"status": "success"})
}

// GetRooms handles fetching customer's chat rooms
func (h *ChatHandler) GetRooms(w http.ResponseWriter, r *http.Request) {
	if r.Method != http.MethodGet {
		http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
		return
	}

	customerID := r.URL.Query().Get("customer_id")
	if customerID == "" {
		http.Error(w, "customer_id is required", http.StatusBadRequest)
		return
	}

	rooms, err := h.chatService.GetUserRooms(r.Context(), customerID)
	if err != nil {
		log.Printf("Error getting rooms: %v", err)
		http.Error(w, err.Error(), http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	json.NewEncoder(w).Encode(rooms)
}
