package myPlant

import (
	"context"

	"github.com/zeromicro/go-zero/core/logx"
	"gorm.io/gorm"
	"sundynix-micro-go/app/plant/api/internal/svc"
	"sundynix-micro-go/app/plant/api/internal/types"
	plantModel "sundynix-micro-go/app/plant/model"
)

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

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

// PlantDetailItem 植物详情 DTO
type PlantDetailItem 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        []CarePlanItem     `json:"carePlans"`
	CareTasks        interface{}        `json:"careTasks"`
	CareRecords      []CareRecordItem   `json:"careRecords"`
	GrowthRecords    []GrowthRecordItem `json:"growthRecords"`
}

type CarePlanItem struct {
	ID           string `json:"id"`
	CreatedAt    string `json:"createdAt"`
	UpdatedAt    string `json:"updatedAt"`
	CreatedAtStr string `json:"createdAtStr"`
	UserID       string `json:"userId"`
	PlantID      string `json:"plantId"`
	Icon         string `json:"icon"`
	Name         string `json:"name"`
	Period       int    `json:"period"`
	TargetAction string `json:"targetAction"`
}

type CareRecordItem struct {
	ID           string `json:"id"`
	CreatedAt    string `json:"createdAt"`
	UpdatedAt    string `json:"updatedAt"`
	CreatedAtStr string `json:"createdAtStr"`
	UserID       string `json:"userId"`
	PlantID      string `json:"plantId"`
	PlanID       string `json:"planId"`
	Name         string `json:"name"`
	Remark       string `json:"remark"`
	Icon         string `json:"icon"`
}

type GrowthRecordItem struct {
	ID           string      `json:"id"`
	CreatedAt    string      `json:"createdAt"`
	UpdatedAt    string      `json:"updatedAt"`
	CreatedAtStr string      `json:"createdAtStr"`
	PlantID      string      `json:"plantId"`
	UserID       string      `json:"userId"`
	Name         string      `json:"name"`
	Tag          string      `json:"tag"`
	Desc         string      `json:"desc"`
	Content      string      `json:"content"`
	ImgList      []ImageInfo `json:"imgList"`
}

func (l *GetPlantDetailLogic) GetPlantDetail(req *types.IdPathReq) (resp interface{}, err error) {
	var myPlant plantModel.MyPlant
	err = l.svcCtx.DB.
		Preload("CarePlans").
		Preload("CareRecords", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		Preload("GrowthRecords", func(db *gorm.DB) *gorm.DB {
			return db.Order("created_at desc")
		}).
		Where("id = ?", req.Id).First(&myPlant).Error
	if err != nil {
		return nil, err
	}

	// 查图片（本地关联表 + FileRpc）
	imgList := queryPlantImages(l.ctx, l.svcCtx, req.Id)

	// 成长记录图片
	growthImgMap := resolveGrowthRecordImages(l.ctx, l.svcCtx, myPlant.GrowthRecords)

	return &PlantDetailItem{
		ID:               myPlant.ID,
		CreatedAt:        FormatTime(myPlant.CreatedAt),
		UpdatedAt:        FormatTime(myPlant.UpdatedAt),
		CreatedAtStr:     FormatTimeShort(myPlant.CreatedAt),
		UserID:           myPlant.UserID,
		Name:             myPlant.Name,
		PlantTime:        FormatTime(myPlant.PlantTime),
		Status:           myPlant.Status,
		Placement:        myPlant.Placement,
		PotMaterial:      myPlant.PotMaterial,
		PotSize:          myPlant.PotSize,
		Sunlight:         myPlant.Sunlight,
		PlantingMaterial: myPlant.PlantingMaterial,
		ImgList:          imgList,
		CarePlans:        toCarePlanItems(myPlant.CarePlans),
		CareTasks:        nil,
		CareRecords:      toCareRecordItems(myPlant.CareRecords),
		GrowthRecords:    toGrowthRecordItems(myPlant.GrowthRecords, growthImgMap),
	}, nil
}

func queryPlantImages(ctx context.Context, svcCtx *svc.ServiceContext, plantID string) []ImageInfo {
	type rel struct {
		OssID string `gorm:"column:sundynix_oss_id"`
	}
	var rels []rel
	svcCtx.DB.Table("sundynix_plant_my_plant_oss").
		Where("sundynix_my_plant_id = ?", plantID).
		Order("sundynix_oss_id asc").
		Find(&rels)

	var ids []string
	for _, r := range rels {
		ids = append(ids, r.OssID)
	}
	infos := FetchFilesByIds(ctx, svcCtx, ids)
	var result []ImageInfo
	for _, id := range ids {
		if f, ok := infos[id]; ok {
			result = append(result, f)
		}
	}
	if result == nil {
		result = []ImageInfo{}
	}
	return result
}

func resolveGrowthRecordImages(ctx context.Context, svcCtx *svc.ServiceContext, records []*plantModel.GrowthRecord) map[string][]ImageInfo {
	var ids []string
	for _, gr := range records {
		ids = append(ids, gr.ID)
	}
	if len(ids) == 0 {
		return nil
	}

	type rel struct {
		GrowthRecordID string `gorm:"column:growth_record_id"`
		OssID          string `gorm:"column:oss_id"`
	}
	var rels []rel
	svcCtx.DB.Table("sundynix_plant_growth_record_oss").
		Where("growth_record_id IN ?", ids).
		Find(&rels)

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

	infos := FetchFilesByIds(ctx, svcCtx, allOssIds)
	result := make(map[string][]ImageInfo)
	for gid, ossIds := range gidMap {
		var imgs []ImageInfo
		for _, oid := range ossIds {
			if f, ok := infos[oid]; ok {
				imgs = append(imgs, f)
			}
		}
		result[gid] = imgs
	}
	return result
}

func toCarePlanItems(plans []*plantModel.CarePlan) []CarePlanItem {
	var items []CarePlanItem
	for _, p := range plans {
		items = append(items, CarePlanItem{
			ID: p.ID, CreatedAt: FormatTime(p.CreatedAt),
			UpdatedAt: FormatTime(p.UpdatedAt), CreatedAtStr: FormatTimeShort(p.CreatedAt),
			UserID: p.UserID, PlantID: p.PlantID, Icon: p.Icon, Name: p.Name,
			Period: p.Period, TargetAction: p.TargetAction,
		})
	}
	if items == nil {
		items = []CarePlanItem{}
	}
	return items
}

func toCareRecordItems(records []*plantModel.CareRecord) []CareRecordItem {
	var items []CareRecordItem
	for _, r := range records {
		items = append(items, CareRecordItem{
			ID: r.ID, CreatedAt: FormatTime(r.CreatedAt),
			UpdatedAt: FormatTime(r.UpdatedAt), CreatedAtStr: FormatTimeShort(r.CreatedAt),
			UserID: r.UserID, PlantID: r.PlantID, PlanID: r.PlanID,
			Name: r.Name, Remark: r.Remark, Icon: r.Icon,
		})
	}
	if items == nil {
		items = []CareRecordItem{}
	}
	return items
}

func toGrowthRecordItems(records []*plantModel.GrowthRecord, imgMap map[string][]ImageInfo) []GrowthRecordItem {
	var items []GrowthRecordItem
	for _, gr := range records {
		item := GrowthRecordItem{
			ID: gr.ID, CreatedAt: FormatTime(gr.CreatedAt),
			UpdatedAt: FormatTime(gr.UpdatedAt), CreatedAtStr: FormatTimeShort(gr.CreatedAt),
			PlantID: gr.PlantID, UserID: gr.UserID, Name: gr.Name,
			Tag: gr.Tag, Desc: gr.Desc, Content: gr.Content,
			ImgList: imgMap[gr.ID],
		}
		if item.ImgList == nil {
			item.ImgList = []ImageInfo{}
		}
		items = append(items, item)
	}
	if items == nil {
		items = []GrowthRecordItem{}
	}
	return items
}
