package myPlant

import (
	"context"
	"fmt"

	"sundynix-micro-go/app/plant/api/internal/svc"
	"sundynix-micro-go/app/plant/api/internal/types"
	plantModel "sundynix-micro-go/app/plant/model"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetMyPlantListLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewGetMyPlantListLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetMyPlantListLogic {
	return &GetMyPlantListLogic{Logger: logx.WithContext(ctx), ctx: ctx, svcCtx: svcCtx}
}

type plantListResp struct {
	List     interface{} `json:"list"`
	Total    int64       `json:"total"`
	Page     int         `json:"page"`
	PageSize int         `json:"pageSize"`
}

type PlantItem struct {
	ID               string      `json:"id"`
	CreatedAt        string      `json:"createdAt"`
	UpdatedAt        string      `json:"updatedAt"`
	CreatedAtStr     string      `json:"createdAtStr"`
	UserID           string      `json:"userId"`
	Name             string      `json:"name"`
	PlantTime        string      `json:"plantTime"`
	Status           int         `json:"status"`
	Placement        string      `json:"placement"`
	PotMaterial      string      `json:"potMaterial"`
	PotSize          string      `json:"potSize"`
	Sunlight         string      `json:"sunlight"`
	PlantingMaterial string      `json:"plantingMaterial"`
	ImgList          []ImageInfo `json:"imgList"`
	CarePlans        interface{} `json:"carePlans"`
	CareTasks        interface{} `json:"careTasks"`
	CareRecords      interface{} `json:"careRecords"`
	GrowthRecords    interface{} `json:"growthRecords"`
}

func (l *GetMyPlantListLogic) GetMyPlantList(req *types.PlantListReq) (resp interface{}, err error) {
	userId := fmt.Sprintf("%v", l.ctx.Value("userId"))

	db := l.svcCtx.DB.Model(&plantModel.MyPlant{}).Where("user_id = ?", userId)
	if req.Name != "" {
		db = db.Where("name like ?", "%"+req.Name+"%")
	}

	var total int64
	db.Count(&total)

	pageSize := req.PageSize
	if pageSize <= 0 {
		pageSize = 20
	}
	page := req.Current
	if page <= 0 {
		page = 1
	}
	offset := (page - 1) * pageSize

	var plants []plantModel.MyPlant
	if err := db.Limit(pageSize).Offset(offset).Order("created_at desc").Find(&plants).Error; err != nil {
		return nil, err
	}

	// 查本地关联表获取图片 ID，再通过 FileRpc 获取完整信息
	imgMap := resolvePlantImages(l.ctx, l.svcCtx, plants)

	var list []PlantItem
	for _, p := range plants {
		list = append(list, PlantItem{
			ID:               p.ID,
			CreatedAt:        FormatTime(p.CreatedAt),
			UpdatedAt:        FormatTime(p.UpdatedAt),
			CreatedAtStr:     FormatTimeShort(p.CreatedAt),
			UserID:           p.UserID,
			Name:             p.Name,
			PlantTime:        FormatTime(p.PlantTime),
			Status:           p.Status,
			Placement:        p.Placement,
			PotMaterial:      p.PotMaterial,
			PotSize:          p.PotSize,
			Sunlight:         p.Sunlight,
			PlantingMaterial: p.PlantingMaterial,
			ImgList:          imgMap[p.ID],
			CarePlans:        nil,
			CareTasks:        nil,
			CareRecords:      nil,
			GrowthRecords:    nil,
		})
	}

	return &plantListResp{List: list, Total: total, Page: page, PageSize: pageSize}, nil
}

// resolvePlantImages 批量查询植物图片
func resolvePlantImages(ctx context.Context, svcCtx *svc.ServiceContext, plants []plantModel.MyPlant) map[string][]ImageInfo {
	var plantIds []string
	for _, p := range plants {
		plantIds = append(plantIds, p.ID)
	}
	if len(plantIds) == 0 {
		return nil
	}

	type rel struct {
		MyPlantID string `gorm:"column:sundynix_my_plant_id"`
		OssID     string `gorm:"column:sundynix_oss_id"`
	}
	var rels []rel
	svcCtx.DB.Table("sundynix_plant_my_plant_oss").
		Where("sundynix_my_plant_id IN ?", plantIds).
		Order("sundynix_oss_id asc").
		Find(&rels)

	var allOssIds []string
	pidMap := make(map[string][]string)
	for _, r := range rels {
		pidMap[r.MyPlantID] = append(pidMap[r.MyPlantID], r.OssID)
		allOssIds = append(allOssIds, r.OssID)
	}

	fileInfos := FetchFilesByIds(ctx, svcCtx, allOssIds)
	result := make(map[string][]ImageInfo)
	for pid, ids := range pidMap {
		var imgs []ImageInfo
		for _, oid := range ids {
			if f, ok := fileInfos[oid]; ok {
				imgs = append(imgs, f)
			}
		}
		if imgs == nil {
			imgs = []ImageInfo{}
		}
		result[pid] = imgs
	}
	return result
}
