package main

// Empyrion activity endpoints: read-only views over empyrion_events for
// faction and structure activity logs.

import (
	"encoding/json"
	"net/http"
	"strconv"
)

// GET /api/instances/{id}/empyrion/factions/{factionId}/activity?limit=200
func (h *httpServer) handleEmpyrionFactionActivity(w http.ResponseWriter, r *http.Request) {
	instanceID := r.PathValue("id")
	factionIDStr := r.PathValue("factionId")
	factionID, err := strconv.Atoi(factionIDStr)
	if err != nil {
		writeError(w, http.StatusBadRequest, "bad_faction_id", "factionId must be integer")
		return
	}
	limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
	if limit <= 0 || limit > 1000 {
		limit = 200
	}

	rows, err := h.db.Pool().Query(r.Context(), `
		SELECT ts, cmd, player_id, player_name, raw
		FROM empyrion_events
		WHERE instance_id = $1
		  AND (raw->>'factionId')::int = $2
		ORDER BY ts DESC
		LIMIT $3`, instanceID, factionID, limit)
	if err != nil {
		writeError(w, http.StatusInternalServerError, "db", err.Error())
		return
	}
	defer rows.Close()

	type activityEvent struct {
		TS         string          `json:"ts"`
		Cmd        string          `json:"cmd"`
		PlayerID   *int            `json:"player_id,omitempty"`
		PlayerName string          `json:"player_name,omitempty"`
		Raw        json.RawMessage `json:"raw"`
	}
	out := []activityEvent{}
	for rows.Next() {
		var e activityEvent
		var ts any
		var pid *int
		var name *string
		var raw []byte
		if err := rows.Scan(&ts, &e.Cmd, &pid, &name, &raw); err != nil {
			continue
		}
		e.TS = formatTS(ts)
		e.PlayerID = pid
		if name != nil {
			e.PlayerName = *name
		}
		e.Raw = raw
		out = append(out, e)
	}
	writeJSON(w, http.StatusOK, map[string]any{"events": out, "count": len(out)})
}

// GET /api/instances/{id}/empyrion/structures/{structureId}/activity?limit=200
func (h *httpServer) handleEmpyrionStructureActivity(w http.ResponseWriter, r *http.Request) {
	instanceID := r.PathValue("id")
	structureIDStr := r.PathValue("structureId")
	structureID, err := strconv.ParseInt(structureIDStr, 10, 64)
	if err != nil {
		writeError(w, http.StatusBadRequest, "bad_structure_id", "structureId must be integer")
		return
	}
	limit, _ := strconv.Atoi(r.URL.Query().Get("limit"))
	if limit <= 0 || limit > 1000 {
		limit = 200
	}

	rows, err := h.db.Pool().Query(r.Context(), `
		SELECT ts, cmd, player_id, player_name, raw
		FROM empyrion_events
		WHERE instance_id = $1
		  AND ((raw->>'id')::bigint = $2 OR (raw->>'structureId')::bigint = $2)
		ORDER BY ts DESC
		LIMIT $3`, instanceID, structureID, limit)
	if err != nil {
		writeError(w, http.StatusInternalServerError, "db", err.Error())
		return
	}
	defer rows.Close()

	type activityEvent struct {
		TS         string          `json:"ts"`
		Cmd        string          `json:"cmd"`
		PlayerID   *int            `json:"player_id,omitempty"`
		PlayerName string          `json:"player_name,omitempty"`
		Raw        json.RawMessage `json:"raw"`
	}
	out := []activityEvent{}
	for rows.Next() {
		var e activityEvent
		var ts any
		var pid *int
		var name *string
		var raw []byte
		if err := rows.Scan(&ts, &e.Cmd, &pid, &name, &raw); err != nil {
			continue
		}
		e.TS = formatTS(ts)
		e.PlayerID = pid
		if name != nil {
			e.PlayerName = *name
		}
		e.Raw = raw
		out = append(out, e)
	}
	writeJSON(w, http.StatusOK, map[string]any{"events": out, "count": len(out)})
}
