package package_series

import (
	"context"
	"time"

	"gorm.io/gorm"

	"github.com/break/junhong_cmp_fiber/internal/model"
	"github.com/break/junhong_cmp_fiber/internal/model/dto"
	"github.com/break/junhong_cmp_fiber/internal/store"
	"github.com/break/junhong_cmp_fiber/internal/store/postgres"
	"github.com/break/junhong_cmp_fiber/pkg/constants"
	"github.com/break/junhong_cmp_fiber/pkg/errors"
	"github.com/break/junhong_cmp_fiber/pkg/middleware"
)

type Service struct {
	packageSeriesStore *postgres.PackageSeriesStore
}

func New(packageSeriesStore *postgres.PackageSeriesStore) *Service {
	return &Service{packageSeriesStore: packageSeriesStore}
}

func (s *Service) Create(ctx context.Context, req *dto.CreatePackageSeriesRequest) (*dto.PackageSeriesResponse, error) {
	currentUserID := middleware.GetUserIDFromContext(ctx)
	if currentUserID == 0 {
		return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
	}

	existing, _ := s.packageSeriesStore.GetByCode(ctx, req.SeriesCode)
	if existing != nil {
		return nil, errors.New(errors.CodeConflict, "系列编码已存在")
	}

	series := &model.PackageSeries{
		SeriesCode:  req.SeriesCode,
		SeriesName:  req.SeriesName,
		Description: req.Description,
		Status:      constants.StatusEnabled,
	}
	series.Creator = currentUserID

	if err := s.packageSeriesStore.Create(ctx, series); err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "创建套餐系列失败")
	}

	return s.toResponse(series), nil
}

func (s *Service) Get(ctx context.Context, id uint) (*dto.PackageSeriesResponse, error) {
	series, err := s.packageSeriesStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
		}
		return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
	}
	return s.toResponse(series), nil
}

func (s *Service) Update(ctx context.Context, id uint, req *dto.UpdatePackageSeriesRequest) (*dto.PackageSeriesResponse, error) {
	currentUserID := middleware.GetUserIDFromContext(ctx)
	if currentUserID == 0 {
		return nil, errors.New(errors.CodeUnauthorized, "未授权访问")
	}

	series, err := s.packageSeriesStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, errors.New(errors.CodeNotFound, "套餐系列不存在")
		}
		return nil, errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
	}

	if req.SeriesName != nil {
		series.SeriesName = *req.SeriesName
	}
	if req.Description != nil {
		series.Description = *req.Description
	}
	series.Updater = currentUserID

	if err := s.packageSeriesStore.Update(ctx, series); err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "更新套餐系列失败")
	}

	return s.toResponse(series), nil
}

func (s *Service) Delete(ctx context.Context, id uint) error {
	_, err := s.packageSeriesStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return errors.New(errors.CodeNotFound, "套餐系列不存在")
		}
		return errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
	}

	if err := s.packageSeriesStore.Delete(ctx, id); err != nil {
		return errors.Wrap(errors.CodeInternalError, err, "删除套餐系列失败")
	}

	return nil
}

func (s *Service) List(ctx context.Context, req *dto.PackageSeriesListRequest) ([]*dto.PackageSeriesResponse, int64, error) {
	opts := &store.QueryOptions{
		Page:     req.Page,
		PageSize: req.PageSize,
		OrderBy:  "id DESC",
	}
	if opts.Page == 0 {
		opts.Page = 1
	}
	if opts.PageSize == 0 {
		opts.PageSize = constants.DefaultPageSize
	}

	filters := make(map[string]interface{})
	if req.SeriesName != nil {
		filters["series_name"] = *req.SeriesName
	}
	if req.Status != nil {
		filters["status"] = *req.Status
	}

	seriesList, total, err := s.packageSeriesStore.List(ctx, opts, filters)
	if err != nil {
		return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询套餐系列列表失败")
	}

	responses := make([]*dto.PackageSeriesResponse, len(seriesList))
	for i, series := range seriesList {
		responses[i] = s.toResponse(series)
	}

	return responses, total, nil
}

func (s *Service) UpdateStatus(ctx context.Context, id uint, status int) error {
	currentUserID := middleware.GetUserIDFromContext(ctx)
	if currentUserID == 0 {
		return errors.New(errors.CodeUnauthorized, "未授权访问")
	}

	series, err := s.packageSeriesStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return errors.New(errors.CodeNotFound, "套餐系列不存在")
		}
		return errors.Wrap(errors.CodeInternalError, err, "获取套餐系列失败")
	}

	series.Status = status
	series.Updater = currentUserID

	if err := s.packageSeriesStore.Update(ctx, series); err != nil {
		return errors.Wrap(errors.CodeInternalError, err, "更新套餐系列状态失败")
	}

	return nil
}

func (s *Service) toResponse(series *model.PackageSeries) *dto.PackageSeriesResponse {
	return &dto.PackageSeriesResponse{
		ID:          series.ID,
		SeriesCode:  series.SeriesCode,
		SeriesName:  series.SeriesName,
		Description: series.Description,
		Status:      series.Status,
		CreatedAt:   series.CreatedAt.Format(time.RFC3339),
		UpdatedAt:   series.UpdatedAt.Format(time.RFC3339),
	}
}
