package user

import (
	"context"
	"strconv"

	modelUser "github.com/perfect-panel/server/internal/model/user"
	"github.com/perfect-panel/server/internal/svc"
	"github.com/perfect-panel/server/internal/types"
	"github.com/perfect-panel/server/pkg/logger"
	"github.com/perfect-panel/server/pkg/tool"
	"github.com/perfect-panel/server/pkg/xerr"
	"github.com/pkg/errors"
	"gorm.io/gorm"
)

type GetFamilyDetailLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logger.Logger
}

func NewGetFamilyDetailLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetFamilyDetailLogic {
	return &GetFamilyDetailLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logger.WithContext(ctx),
	}
}

func (l *GetFamilyDetailLogic) GetFamilyDetail(req *types.GetFamilyDetailRequest) (*types.FamilyDetail, error) {
	var family modelUser.UserFamily
	err := l.svcCtx.DB.WithContext(l.ctx).
		Where("id = ? AND deleted_at IS NULL", req.Id).
		First(&family).Error
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.FamilyNotExist), "family does not exist")
		}
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query family detail failed")
	}

	var members []modelUser.UserFamilyMember
	if err = l.svcCtx.DB.WithContext(l.ctx).
		Where("family_id = ? AND deleted_at IS NULL", family.Id).
		Order("joined_at DESC").
		Find(&members).Error; err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query family members failed")
	}

	userIDs := make([]int64, 0, len(members)+1)
	userIDs = append(userIDs, family.OwnerUserId)
	activeMemberCount := int64(0)
	for _, member := range members {
		userIDs = append(userIDs, member.UserId)
		if member.Status == modelUser.FamilyMemberActive {
			activeMemberCount++
		}
	}

	identifierMap, identifierErr := findUserIdentifiers(l.ctx, l.svcCtx.DB, userIDs)
	if identifierErr != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "query family member identifiers failed")
	}

	// 查出所有成员的设备，构建 userId → deviceNo 映射 + deviceType 映射
	deviceNoMap := make(map[int64]string)
	deviceTypeMap := make(map[int64]string)
	devices, _, _ := l.svcCtx.UserModel.QueryDeviceListByUserIds(l.ctx, userIDs)
	for _, d := range devices {
		if _, exists := deviceNoMap[d.UserId]; !exists {
			deviceNoMap[d.UserId] = tool.DeviceIdToHash(d.Id)
			deviceTypeMap[d.UserId] = parseDeviceType(d.UserAgent)
		}
	}

	memberItems := make([]types.FamilyMemberItem, 0, len(members))
	for _, member := range members {
		info := identifierMap[member.UserId]
		identifier := info.Identifier
		authType := info.AuthType
		if identifier == "" {
			identifier = strconv.FormatInt(member.UserId, 10)
		}

		memberItem := types.FamilyMemberItem{
			UserId:     member.UserId,
			Identifier: identifier,
			AuthType:   authType,
			DeviceNo:   deviceNoMap[member.UserId],
			DeviceType: deviceTypeMap[member.UserId],
			Role:       member.Role,
			RoleName:   mapFamilyRoleName(member.Role),
			Status:     member.Status,
			StatusName: mapFamilyMemberStatusName(member.Status),
			JoinSource: member.JoinSource,
			JoinedAt:   member.JoinedAt.Unix(),
		}
		if member.LeftAt != nil {
			memberItem.LeftAt = member.LeftAt.Unix()
		}
		memberItems = append(memberItems, memberItem)
	}

	ownerInfo := identifierMap[family.OwnerUserId]
	ownerIdentifier := ownerInfo.Identifier
	ownerAuthType := ownerInfo.AuthType
	if ownerIdentifier == "" {
		ownerIdentifier = strconv.FormatInt(family.OwnerUserId, 10)
	}

	return &types.FamilyDetail{
		Summary: types.FamilySummary{
			FamilyId:          family.Id,
			OwnerUserId:       family.OwnerUserId,
			OwnerIdentifier:   ownerIdentifier,
			OwnerAuthType:     ownerAuthType,
			Status:            mapFamilyStatus(family.Status),
			ActiveMemberCount: activeMemberCount,
			MaxMembers:        family.MaxMembers,
			CreatedAt:         family.CreatedAt.Unix(),
			UpdatedAt:         family.UpdatedAt.Unix(),
		},
		Members: memberItems,
	}, nil
}
