package org

import (
	"net/http"
	"strings"

	"github.com/tidbcloud/AgentTeam/internal/api"
	"github.com/tidbcloud/AgentTeam/internal/api/dto"
	"github.com/tidbcloud/AgentTeam/internal/api/dto/converter"
)

// List handles GET /api/v1/orgs/:orgId/units.
// It returns all organizational units for the specified organization.
func (handler *UnitHandler) List(r api.AuthenticatedRequest) (api.Response, error) {
	orgs, ok := handler.organizationProvider()
	if !ok {
		return api.Response{}, api.NewHTTPError(http.StatusNotFound, "Organization provider not installed")
	}

	organizationID := strings.TrimSpace(r.Gin.Param("orgId"))
	if organizationID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "orgId is required")
	}

	units, err := orgs.ListOrganizationUnitsForUser(r.Context(), r.UserID(), organizationID)
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToOrgUnitViews(units)), nil
}

// Create handles POST /api/v1/orgs/:orgId/units.
// It creates a new organizational unit within the specified organization.
func (handler *UnitHandler) Create(r api.AuthenticatedJSON[dto.OrganizationUnitCreateRequest]) (api.Response, error) {
	orgs, ok := handler.organizationProvider()
	if !ok {
		return api.Response{}, api.NewHTTPError(http.StatusNotFound, "Organization provider not installed")
	}

	organizationID := strings.TrimSpace(r.Gin.Param("orgId"))
	if organizationID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "orgId is required")
	}

	request := r.Body

	unit, err := orgs.CreateOrganizationUnitForUser(r.Context(), r.UserID(), organizationID, createOrganizationUnitParams(request))
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToOrgUnitView(unit)), nil
}

// ListMembers handles GET /api/v1/orgs/:orgId/units/:unitId/members.
// It returns all members belonging to the specified organizational unit.
func (handler *UnitHandler) ListMembers(r api.AuthenticatedRequest) (api.Response, error) {
	orgs, ok := handler.organizationProvider()
	if !ok {
		return api.Response{}, api.NewHTTPError(http.StatusNotFound, "Organization provider not installed")
	}

	organizationID := strings.TrimSpace(r.Gin.Param("orgId"))
	unitID := strings.TrimSpace(r.Gin.Param("unitId"))
	if organizationID == "" || unitID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "Invalid request")
	}

	members, err := orgs.ListOrganizationUnitMembersForUser(r.Context(), r.UserID(), organizationID, unitID)
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToOrgUnitMemberViews(members)), nil
}

// CreateMember handles POST /api/v1/orgs/:orgId/units/:unitId/members.
// It adds a member to the specified organizational unit.
func (handler *UnitHandler) CreateMember(r api.AuthenticatedJSON[dto.OrganizationUnitMemberCreateRequest]) (api.Response, error) {
	orgs, ok := handler.organizationProvider()
	if !ok {
		return api.Response{}, api.NewHTTPError(http.StatusNotFound, "Organization provider not installed")
	}

	organizationID := strings.TrimSpace(r.Gin.Param("orgId"))
	unitID := strings.TrimSpace(r.Gin.Param("unitId"))
	if organizationID == "" || unitID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "Invalid request")
	}

	request := r.Body

	member, err := orgs.AddOrganizationUnitMemberForUser(r.Context(), r.UserID(), organizationID, unitID, addOrganizationUnitMemberParams(request))
	if err != nil {
		return api.Response{}, err
	}
	return api.OK(converter.ToOrgUnitMemberView(member)), nil
}

// RemoveMember handles DELETE /api/v1/orgs/:orgId/units/:unitId/members/:memberId.
// It removes a member from the specified organizational unit.
func (handler *UnitHandler) RemoveMember(r api.AuthenticatedRequest) (api.Response, error) {
	orgs, ok := handler.organizationProvider()
	if !ok {
		return api.Response{}, api.NewHTTPError(http.StatusNotFound, "Organization provider not installed")
	}

	organizationID := strings.TrimSpace(r.Gin.Param("orgId"))
	unitID := strings.TrimSpace(r.Gin.Param("unitId"))
	memberID := strings.TrimSpace(r.Gin.Param("memberId"))
	if organizationID == "" || unitID == "" || memberID == "" {
		return api.Response{}, api.NewHTTPError(http.StatusBadRequest, "Invalid request")
	}

	if err := orgs.RemoveOrganizationUnitMemberForUser(r.Context(), r.UserID(), organizationID, unitID, memberID); err != nil {
		return api.Response{}, err
	}
	return api.OK(dto.EmptyResponse{}), nil
}
