package main

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

	"go.mongodb.org/mongo-driver/v2/bson"

	"logjensticks/internal/auth"
	"logjensticks/internal/db"
)

type createLaneRequest struct {
	LaneID          *string `json:"lane_id"`
	PickupState     *string `json:"pickup_state"`
	DropoffState    *string `json:"dropoff_state"`
	PickupAddress   *string `json:"pickup_address"`
	DropoffAddress  *string `json:"dropoff_address"`
}

func handleCreateLane(dbc *db.Client) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		session := auth.SessionFromContext(r.Context())
		if session.Role != "broker" {
			writeError(w, http.StatusForbidden, "FORBIDDEN", "brokers only")
			return
		}

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

		hasLaneID    := req.LaneID != nil && *req.LaneID != ""
		hasStates    := req.PickupState != nil && *req.PickupState != "" &&
		                req.DropoffState != nil && *req.DropoffState != ""
		hasAddresses := req.PickupAddress != nil && *req.PickupAddress != "" &&
		                req.DropoffAddress != nil && *req.DropoffAddress != ""

		if !hasLaneID && !hasStates && !hasAddresses {
			writeError(w, http.StatusBadRequest, "VALIDATION_ERROR",
				"provide at least a lane ID, both state codes, or both addresses")
			return
		}

		var creatingUser struct {
			ID bson.ObjectID `bson:"_id"`
		}
		err := dbc.Users().FindOne(r.Context(),
			bson.D{{Key: "username", Value: session.Username}},
		).Decode(&creatingUser)
		if err != nil {
			writeError(w, http.StatusInternalServerError, "SERVER_ERROR", "failed to resolve user")
			return
		}

		doc := bson.D{
			{Key: "lane_id",          Value: req.LaneID},
			{Key: "pickup_state",     Value: req.PickupState},
			{Key: "dropoff_state",    Value: req.DropoffState},
			{Key: "pickup_address",   Value: req.PickupAddress},
			{Key: "dropoff_address",  Value: req.DropoffAddress},
			{Key: "bidding_carriers", Value: bson.A{}},
			{Key: "created_by",       Value: session.Username},
			{Key: "created_by_id",    Value: creatingUser.ID},
		}

		result, err := dbc.Lanes().InsertOne(r.Context(), doc)
		if err != nil {
			writeError(w, http.StatusInternalServerError, "SERVER_ERROR", "failed to create lane")
			return
		}

		writeSuccess(w, http.StatusCreated, map[string]any{
			"id": result.InsertedID,
		})
	}
}
