package service

import (
	"context"
	"errors"

	"github.com/user-management-system/internal/domain"
	"github.com/user-management-system/internal/repository"
)

// PermissionService 权限服务
type PermissionService struct {
	permissionRepo *repository.PermissionRepository
}

// NewPermissionService 创建权限服务
func NewPermissionService(
	permissionRepo *repository.PermissionRepository,
) *PermissionService {
	return &PermissionService{
		permissionRepo: permissionRepo,
	}
}

// CreatePermissionRequest 创建权限请求
type CreatePermissionRequest struct {
	Name        string `json:"name" binding:"required"`
	Code        string `json:"code" binding:"required"`
	Type        int    `json:"type" binding:"required"`
	Description string `json:"description"`
	ParentID    *int64 `json:"parent_id"`
	Path        string `json:"path"`
	Method      string `json:"method"`
	Sort        int    `json:"sort"`
	Icon        string `json:"icon"`
}

// UpdatePermissionRequest 更新权限请求
type UpdatePermissionRequest struct {
	Name        string `json:"name"`
	Description string `json:"description"`
	ParentID    *int64 `json:"parent_id"`
	Path        string `json:"path"`
	Method      string `json:"method"`
	Sort        int    `json:"sort"`
	Icon        string `json:"icon"`
}

// CreatePermission 创建权限
func (s *PermissionService) CreatePermission(ctx context.Context, req *CreatePermissionRequest) (*domain.Permission, error) {
	// 检查权限代码是否已存在
	exists, err := s.permissionRepo.ExistsByCode(ctx, req.Code)
	if err != nil {
		return nil, err
	}
	if exists {
		return nil, errors.New("权限代码已存在")
	}

	// 检查父权限是否存在
	if req.ParentID != nil {
		_, err := s.permissionRepo.GetByID(ctx, *req.ParentID)
		if err != nil {
			return nil, errors.New("父权限不存在")
		}
	}

	// 创建权限
	permission := &domain.Permission{
		Name:        req.Name,
		Code:        req.Code,
		Type:        domain.PermissionType(req.Type),
		Description: req.Description,
		ParentID:    req.ParentID,
		Level:       1,
		Path:        req.Path,
		Method:      req.Method,
		Sort:        req.Sort,
		Icon:        req.Icon,
		Status:      domain.PermissionStatusEnabled,
	}

	if req.ParentID != nil {
		permission.Level = 2
	}

	if err := s.permissionRepo.Create(ctx, permission); err != nil {
		return nil, err
	}

	return permission, nil
}

// UpdatePermission 更新权限
func (s *PermissionService) UpdatePermission(ctx context.Context, permissionID int64, req *UpdatePermissionRequest) (*domain.Permission, error) {
	permission, err := s.permissionRepo.GetByID(ctx, permissionID)
	if err != nil {
		return nil, errors.New("权限不存在")
	}

	// 检查父权限是否存在
	if req.ParentID != nil {
		if *req.ParentID == permissionID {
			return nil, errors.New("不能将权限设置为自己的父权限")
		}
		_, err := s.permissionRepo.GetByID(ctx, *req.ParentID)
		if err != nil {
			return nil, errors.New("父权限不存在")
		}
		permission.ParentID = req.ParentID
	}

	// 更新字段
	if req.Name != "" {
		permission.Name = req.Name
	}
	if req.Description != "" {
		permission.Description = req.Description
	}
	if req.Path != "" {
		permission.Path = req.Path
	}
	if req.Method != "" {
		permission.Method = req.Method
	}
	if req.Sort > 0 {
		permission.Sort = req.Sort
	}
	if req.Icon != "" {
		permission.Icon = req.Icon
	}

	if err := s.permissionRepo.Update(ctx, permission); err != nil {
		return nil, err
	}

	return permission, nil
}

// DeletePermission 删除权限
func (s *PermissionService) DeletePermission(ctx context.Context, permissionID int64) error {
	_, err := s.permissionRepo.GetByID(ctx, permissionID)
	if err != nil {
		return errors.New("权限不存在")
	}

	// 检查是否有子权限
	children, err := s.permissionRepo.ListByParentID(ctx, permissionID)
	if err == nil && len(children) > 0 {
		return errors.New("存在子权限，无法删除")
	}

	return s.permissionRepo.Delete(ctx, permissionID)
}

// GetPermission 获取权限信息
func (s *PermissionService) GetPermission(ctx context.Context, permissionID int64) (*domain.Permission, error) {
	return s.permissionRepo.GetByID(ctx, permissionID)
}

// ListPermissions 获取权限列表
type ListPermissionRequest struct {
	Page     int    `json:"page"`
	PageSize int    `json:"page_size"`
	Type     int    `json:"type"`
	Status   int    `json:"status"`
	Keyword  string `json:"keyword"`
}

func (s *PermissionService) ListPermissions(ctx context.Context, req *ListPermissionRequest) ([]*domain.Permission, int64, error) {
	if req.Page <= 0 {
		req.Page = 1
	}
	if req.PageSize <= 0 {
		req.PageSize = 20
	}
	offset := (req.Page - 1) * req.PageSize

	if req.Keyword != "" {
		return s.permissionRepo.Search(ctx, req.Keyword, offset, req.PageSize)
	}

	// Type > 0 表示按类型过滤；0 表示不过滤（查全部）
	if req.Type > 0 {
		return s.permissionRepo.ListByType(ctx, domain.PermissionType(req.Type), offset, req.PageSize)
	}

	// Status > 0 表示按状态过滤；0 表示不过滤（查全部）
	if req.Status > 0 {
		return s.permissionRepo.ListByStatus(ctx, domain.PermissionStatus(req.Status), offset, req.PageSize)
	}

	return s.permissionRepo.List(ctx, offset, req.PageSize)
}

// UpdatePermissionStatus 更新权限状态
func (s *PermissionService) UpdatePermissionStatus(ctx context.Context, permissionID int64, status domain.PermissionStatus) error {
	return s.permissionRepo.UpdateStatus(ctx, permissionID, status)
}

// GetPermissionTree 获取权限树
func (s *PermissionService) GetPermissionTree(ctx context.Context) ([]*domain.Permission, error) {
	// 获取所有权限
	permissions, _, err := s.permissionRepo.List(ctx, 0, 1000)
	if err != nil {
		return nil, err
	}

	// 构建树形结构
	return s.buildPermissionTree(permissions, 0), nil
}

// buildPermissionTree 构建权限树
func (s *PermissionService) buildPermissionTree(permissions []*domain.Permission, parentID int64) []*domain.Permission {
	var tree []*domain.Permission
	for _, perm := range permissions {
		if (parentID == 0 && perm.ParentID == nil) || (perm.ParentID != nil && *perm.ParentID == parentID) {
			perm.Children = s.buildPermissionTree(permissions, perm.ID)
			tree = append(tree, perm)
		}
	}
	return tree
}
