package org

import (
	"fmt"
	"strings"
	"time"

	"github.com/veypi/vbase/internal/api/middleware"
	"github.com/veypi/vbase/internal/model"
	"github.com/veypi/vigo"
	"gorm.io/gorm"
)

// ListRequest 组织列表请求
type ListRequest struct {
	Page     int    `json:"page" src:"query" default:"1" desc:"页码"`
	PageSize int    `json:"page_size" src:"query" default:"10" desc:"每页数量"`
	Keyword  string `json:"keyword" src:"query" desc:"搜索关键词"`
}

// ListResponse 组织列表响应
type ListResponse struct {
	Items      []OrgInfo `json:"items"`
	Total      int64     `json:"total"`
	Page       int       `json:"page"`
	PageSize   int       `json:"page_size"`
	TotalPages int       `json:"total_pages"`
}

// OrgInfo 组织信息
type OrgInfo struct {
	ID          string `json:"id"`
	Name        string `json:"name"`
	Code        string `json:"code"`
	OwnerID     string `json:"owner_id"`
	ParentID    string `json:"parent_id,omitempty"`
	Path        string `json:"path"`
	Level       int    `json:"level"`
	LeaderID    string `json:"leader_id,omitempty"`
	Description string `json:"description"`
	Logo        string `json:"logo"`
	Status      int    `json:"status"`
	MaxMembers  int    `json:"max_members"`
	CreatedAt   string `json:"created_at"`
	UpdatedAt   string `json:"updated_at"`
	// 当前用户在该组织的信息
	MyRoles  []string `json:"my_roles,omitempty"`
	MyStatus int      `json:"my_status,omitempty"`
}

// List 获取当前用户的组织列表
func List(x *vigo.X, req *ListRequest) (*ListResponse, error) {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return nil, vigo.ErrNotAuthorized
	}

	if req.Page < 1 {
		req.Page = 1
	}
	if req.PageSize < 1 || req.PageSize > 100 {
		req.PageSize = 10
	}

	// 查询用户所属的组织ID
	var memberOrgs []model.OrgMember
	if err := model.DB.Where("user_id = ? AND status = ?", userID, model.MemberStatusActive).Find(&memberOrgs).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	if len(memberOrgs) == 0 {
		return &ListResponse{
			Items:      []OrgInfo{},
			Total:      0,
			Page:       req.Page,
			PageSize:   req.PageSize,
			TotalPages: 0,
		}, nil
	}

	orgIDs := make([]string, 0, len(memberOrgs))
	memberMap := make(map[string]*model.OrgMember)
	for _, m := range memberOrgs {
		orgIDs = append(orgIDs, m.OrgID)
		memberMap[m.OrgID] = &m
	}

	// 查询组织详情
	var total int64
	query := model.DB.Model(&model.Org{}).Where("id IN ?", orgIDs)
	if req.Keyword != "" {
		query = query.Where("name LIKE ? OR code LIKE ?", "%"+req.Keyword+"%", "%"+req.Keyword+"%")
	}

	if err := query.Count(&total).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	var orgs []model.Org
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Order("created_at DESC").Find(&orgs).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	items := make([]OrgInfo, 0, len(orgs))
	for _, o := range orgs {
		info := toOrgInfo(&o)
		if m, ok := memberMap[o.ID]; ok {
			info.MyRoles = parseRoles(m.RoleIDs)
			info.MyStatus = m.Status
		}
		items = append(items, info)
	}

	totalPages := int((total + int64(req.PageSize) - 1) / int64(req.PageSize))

	return &ListResponse{
		Items:      items,
		Total:      total,
		Page:       req.Page,
		PageSize:   req.PageSize,
		TotalPages: totalPages,
	}, nil
}

// CreateRequest 创建组织请求
type CreateRequest struct {
	Name        string  `json:"name" src:"json" desc:"组织名称"`
	Code        string  `json:"code" src:"json" desc:"组织编码"`
	ParentID    *string `json:"parent_id" src:"json" desc:"父组织ID"`
	Description *string `json:"description" src:"json" desc:"描述"`
	Logo        *string `json:"logo" src:"json" desc:"Logo"`
	MaxMembers  *int    `json:"max_members" src:"json" desc:"最大成员数"`
}

// Create 创建组织
func Create(x *vigo.X, req *CreateRequest) (*OrgInfo, error) {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return nil, vigo.ErrNotAuthorized
	}

	// 检查编码是否已存在
	var count int64
	model.DB.Model(&model.Org{}).Where("code = ?", req.Code).Count(&count)
	if count > 0 {
		return nil, vigo.ErrArgInvalid.WithString("organization code already exists")
	}

	// 构建组织路径
	path := "/" + req.Code
	level := 0
	if req.ParentID != nil && *req.ParentID != "" {
		var parent model.Org
		if err := model.DB.First(&parent, "id = ?", *req.ParentID).Error; err != nil {
			return nil, vigo.ErrArgInvalid.WithString("parent organization not found")
		}
		path = parent.Path + "/" + req.Code
		level = parent.Level + 1
	}

	org := &model.Org{
		Name:       req.Name,
		Code:       req.Code,
		OwnerID:    userID,
		Path:       path,
		Level:      level,
		Status:     model.OrgStatusActive,
		MaxMembers: 100,
	}

	if req.ParentID != nil {
		org.ParentID = req.ParentID
	}
	if req.Description != nil {
		org.Description = *req.Description
	}
	if req.Logo != nil {
		org.Logo = *req.Logo
	}
	if req.MaxMembers != nil {
		org.MaxMembers = *req.MaxMembers
	}

	err := model.DB.Transaction(func(tx *gorm.DB) error {
		// 创建组织
		if err := tx.Create(org).Error; err != nil {
			return err
		}

		// 创建成员关系（所有者）
		member := &model.OrgMember{
			OrgID:  org.ID,
			UserID: userID,
			Status: model.MemberStatusActive,
			JoinedAt: time.Now().Format("2006-01-02 15:04:05"),
		}
		return tx.Create(member).Error
	})

	if err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	info := toOrgInfo(org)
	return &info, nil
}

// GetRequest 获取组织请求
type GetRequest struct {
	ID string `json:"id" src:"path@org_id" desc:"组织ID"`
}

// Get 获取组织详情
func Get(x *vigo.X, req *GetRequest) (*OrgInfo, error) {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return nil, vigo.ErrNotAuthorized
	}

	var org model.Org
	if err := model.DB.First(&org, "id = ?", req.ID).Error; err != nil {
		return nil, vigo.ErrNotFound
	}

	// 检查用户是否是组织成员
	var member model.OrgMember
	if err := model.DB.Where("org_id = ? AND user_id = ?", req.ID, userID).First(&member).Error; err != nil {
		return nil, vigo.ErrForbidden.WithString("you are not a member of this organization")
	}

	info := toOrgInfo(&org)
	info.MyRoles = parseRoles(member.RoleIDs)
	info.MyStatus = member.Status
	return &info, nil
}

// UpdateRequest 更新组织请求
type UpdateRequest struct {
	ID          string  `json:"id" src:"path@org_id" desc:"组织ID"`
	Name        *string `json:"name" src:"json" desc:"组织名称"`
	Description *string `json:"description" src:"json" desc:"描述"`
	Logo        *string `json:"logo" src:"json" desc:"Logo"`
	LeaderID    *string `json:"leader_id" src:"json" desc:"负责人ID"`
	MaxMembers  *int    `json:"max_members" src:"json" desc:"最大成员数"`
	Status      *int    `json:"status" src:"json" desc:"状态"`
}

// Update 更新组织
func Update(x *vigo.X, req *UpdateRequest) (*OrgInfo, error) {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return nil, vigo.ErrNotAuthorized
	}

	var org model.Org
	if err := model.DB.First(&org, "id = ?", req.ID).Error; err != nil {
		return nil, vigo.ErrNotFound
	}

	// 检查权限（只有所有者可以修改）
	if org.OwnerID != userID {
		return nil, vigo.ErrForbidden.WithString("only organization owner can update")
	}

	updates := make(map[string]interface{})
	if req.Name != nil {
		updates["name"] = *req.Name
	}
	if req.Description != nil {
		updates["description"] = *req.Description
	}
	if req.Logo != nil {
		updates["logo"] = *req.Logo
	}
	if req.LeaderID != nil {
		updates["leader_id"] = *req.LeaderID
	}
	if req.MaxMembers != nil {
		updates["max_members"] = *req.MaxMembers
	}
	if req.Status != nil {
		updates["status"] = *req.Status
	}

	if len(updates) > 0 {
		if err := model.DB.Model(&org).Updates(updates).Error; err != nil {
			return nil, vigo.ErrInternalServer.WithError(err)
		}
	}

	info := toOrgInfo(&org)
	return &info, nil
}

// DeleteRequest 删除组织请求
type DeleteRequest struct {
	ID string `json:"id" src:"path@org_id" desc:"组织ID"`
}

// Delete 删除组织
func Delete(x *vigo.X, req *DeleteRequest) error {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return vigo.ErrNotAuthorized
	}

	var org model.Org
	if err := model.DB.First(&org, "id = ?", req.ID).Error; err != nil {
		return vigo.ErrNotFound
	}

	// 检查权限（只有所有者可以删除）
	if org.OwnerID != userID {
		return vigo.ErrForbidden.WithString("only organization owner can delete")
	}

	// 检查是否有子组织
	var childCount int64
	model.DB.Model(&model.Org{}).Where("parent_id = ?", req.ID).Count(&childCount)
	if childCount > 0 {
		return vigo.ErrArgInvalid.WithString("cannot delete organization with sub-organizations")
	}

	// 软删除
	if err := model.DB.Delete(&org).Error; err != nil {
		return vigo.ErrInternalServer.WithError(err)
	}

	return nil
}

// TreeResponse 组织树响应
type TreeResponse struct {
	OrgInfo
	Children []TreeResponse `json:"children,omitempty"`
}

// Tree 获取组织树
func Tree(x *vigo.X) ([]TreeResponse, error) {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return nil, vigo.ErrNotAuthorized
	}

	// 获取用户所属的所有组织ID
	var memberOrgs []model.OrgMember
	if err := model.DB.Where("user_id = ? AND status = ?", userID, model.MemberStatusActive).Find(&memberOrgs).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	if len(memberOrgs) == 0 {
		return []TreeResponse{}, nil
	}

	orgIDs := make([]string, 0, len(memberOrgs))
	for _, m := range memberOrgs {
		orgIDs = append(orgIDs, m.OrgID)
	}

	// 获取所有组织
	var orgs []model.Org
	if err := model.DB.Where("id IN ?", orgIDs).Order("path").Find(&orgs).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	// 构建树
	return buildOrgTree(orgs, ""), nil
}

func buildOrgTree(orgs []model.Org, parentID string) []TreeResponse {
	var result []TreeResponse
	for _, o := range orgs {
		if (parentID == "" && (o.ParentID == nil || *o.ParentID == "")) ||
			(o.ParentID != nil && *o.ParentID == parentID) {
			node := TreeResponse{
				OrgInfo: toOrgInfo(&o),
			}
			node.Children = buildOrgTree(orgs, o.ID)
			result = append(result, node)
		}
	}
	return result
}

// helper functions

func toOrgInfo(o *model.Org) OrgInfo {
	info := OrgInfo{
		ID:          o.ID,
		Name:        o.Name,
		Code:        o.Code,
		OwnerID:     o.OwnerID,
		Path:        o.Path,
		Level:       o.Level,
		Description: o.Description,
		Logo:        o.Logo,
		Status:      o.Status,
		MaxMembers:  o.MaxMembers,
		CreatedAt:   o.CreatedAt.Format("2006-01-02 15:04:05"),
		UpdatedAt:   o.UpdatedAt.Format("2006-01-02 15:04:05"),
	}
	if o.ParentID != nil {
		info.ParentID = *o.ParentID
	}
	if o.LeaderID != nil {
		info.LeaderID = *o.LeaderID
	}
	return info
}

func parseRoles(roleIDs string) []string {
	if roleIDs == "" {
		return []string{}
	}
	return strings.Split(roleIDs, ",")
}

func formatRoleID(roleIDs []string) string {
	return strings.Join(roleIDs, ",")
}

// ListMembersRequest 成员列表请求
type ListMembersRequest struct {
	OrgID    string `json:"org_id" src:"path@org_id" desc:"组织ID"`
	Page     int    `json:"page" src:"query" default:"1" desc:"页码"`
	PageSize int    `json:"page_size" src:"query" default:"10" desc:"每页数量"`
	Status   *int   `json:"status" src:"query" desc:"状态筛选"`
}

// MemberInfo 成员信息
type MemberInfo struct {
	ID         string   `json:"id"`
	OrgID      string   `json:"org_id"`
	UserID     string   `json:"user_id"`
	Username   string   `json:"username"`
	Nickname   string   `json:"nickname"`
	Avatar     string   `json:"avatar"`
	Email      string   `json:"email"`
	Roles      []string `json:"roles"`
	Position   string   `json:"position"`
	Department string   `json:"department"`
	JoinedAt   string   `json:"joined_at"`
	Status     int      `json:"status"`
}

// ListMembers 获取组织成员列表
func ListMembers(x *vigo.X, req *ListMembersRequest) (*ListResponse, error) {
	userID := middleware.CurrentUser(x)
	if userID == "" {
		return nil, vigo.ErrNotAuthorized
	}

	if req.Page < 1 {
		req.Page = 1
	}
	if req.PageSize < 1 || req.PageSize > 100 {
		req.PageSize = 10
	}

	// 检查用户是否是组织成员
	var currentMember model.OrgMember
	if err := model.DB.Where("org_id = ? AND user_id = ?", req.OrgID, userID).First(&currentMember).Error; err != nil {
		return nil, vigo.ErrForbidden.WithString("you are not a member of this organization")
	}

	var total int64
	query := model.DB.Model(&model.OrgMember{}).Where("org_id = ?", req.OrgID)
	if req.Status != nil {
		query = query.Where("status = ?", *req.Status)
	}

	if err := query.Count(&total).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	var members []model.OrgMember
	offset := (req.Page - 1) * req.PageSize
	if err := query.Offset(offset).Limit(req.PageSize).Find(&members).Error; err != nil {
		return nil, vigo.ErrInternalServer.WithError(err)
	}

	items := make([]OrgInfo, 0) // 这里需要修改返回类型
	_ = items

	// 获取用户信息
	memberInfos := make([]MemberInfo, 0, len(members))
	for _, m := range members {
		var user model.User
		if err := model.DB.First(&user, "id = ?", m.UserID).Error; err != nil {
			continue
		}
		memberInfos = append(memberInfos, MemberInfo{
			ID:         m.ID,
			OrgID:      m.OrgID,
			UserID:     m.UserID,
			Username:   user.Username,
			Nickname:   user.Nickname,
			Avatar:     user.Avatar,
			Email:      user.Email,
			Roles:      parseRoles(m.RoleIDs),
			Position:   m.Position,
			Department: m.Department,
			JoinedAt:   m.JoinedAt,
			Status:     m.Status,
		})
	}

	_ = memberInfos
	return nil, fmt.Errorf("not fully implemented")
}
