package carrier

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 {
	carrierStore *postgres.CarrierStore
}

func New(carrierStore *postgres.CarrierStore) *Service {
	return &Service{carrierStore: carrierStore}
}

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

	existing, _ := s.carrierStore.GetByCode(ctx, req.CarrierCode)
	if existing != nil {
		return nil, errors.New(errors.CodeCarrierCodeExists, "运营商编码已存在")
	}

	carrier := &model.Carrier{
		CarrierCode:  req.CarrierCode,
		CarrierName:  req.CarrierName,
		CarrierType:  req.CarrierType,
		Description:  req.Description,
		Status:       constants.StatusEnabled,
		DataResetDay: 1,
	}
	if req.DataResetDay != nil {
		carrier.DataResetDay = *req.DataResetDay
	}
	if req.RealnameLinkType != nil {
		carrier.RealnameLinkType = *req.RealnameLinkType
	}
	if req.RealnameLinkTemplate != nil {
		carrier.RealnameLinkTemplate = *req.RealnameLinkTemplate
	}
	carrier.Creator = currentUserID

	if err := s.carrierStore.Create(ctx, carrier); err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "创建运营商失败")
	}

	return s.toResponse(carrier), nil
}

func (s *Service) Get(ctx context.Context, id uint) (*dto.CarrierResponse, error) {
	carrier, err := s.carrierStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, errors.New(errors.CodeCarrierNotFound, "运营商不存在")
		}
		return nil, errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
	}
	return s.toResponse(carrier), nil
}

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

	carrier, err := s.carrierStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return nil, errors.New(errors.CodeCarrierNotFound, "运营商不存在")
		}
		return nil, errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
	}

	if req.CarrierName != nil {
		carrier.CarrierName = *req.CarrierName
	}
	if req.Description != nil {
		carrier.Description = *req.Description
	}
	if req.DataResetDay != nil {
		carrier.DataResetDay = *req.DataResetDay
	}
	if req.RealnameLinkType != nil {
		carrier.RealnameLinkType = *req.RealnameLinkType
	}
	if req.RealnameLinkTemplate != nil {
		carrier.RealnameLinkTemplate = *req.RealnameLinkTemplate
	}
	if carrier.RealnameLinkType == "template" && carrier.RealnameLinkTemplate == "" {
		return nil, errors.New(errors.CodeInvalidParam, "模板URL类型必须提供实名链接模板")
	}
	carrier.Updater = currentUserID

	if err := s.carrierStore.Update(ctx, carrier); err != nil {
		return nil, errors.Wrap(errors.CodeInternalError, err, "更新运营商失败")
	}

	return s.toResponse(carrier), nil
}

func (s *Service) Delete(ctx context.Context, id uint) error {
	_, err := s.carrierStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return errors.New(errors.CodeCarrierNotFound, "运营商不存在")
		}
		return errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
	}

	if err := s.carrierStore.Delete(ctx, id); err != nil {
		return errors.Wrap(errors.CodeInternalError, err, "删除运营商失败")
	}

	return nil
}

func (s *Service) List(ctx context.Context, req *dto.CarrierListRequest) ([]*dto.CarrierResponse, 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.CarrierType != nil {
		filters["carrier_type"] = *req.CarrierType
	}
	if req.CarrierName != nil {
		filters["carrier_name"] = *req.CarrierName
	}
	if req.Status != nil {
		filters["status"] = *req.Status
	}

	carriers, total, err := s.carrierStore.List(ctx, opts, filters)
	if err != nil {
		return nil, 0, errors.Wrap(errors.CodeInternalError, err, "查询运营商列表失败")
	}

	responses := make([]*dto.CarrierResponse, len(carriers))
	for i, c := range carriers {
		responses[i] = s.toResponse(c)
	}

	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, "未授权访问")
	}

	carrier, err := s.carrierStore.GetByID(ctx, id)
	if err != nil {
		if err == gorm.ErrRecordNotFound {
			return errors.New(errors.CodeCarrierNotFound, "运营商不存在")
		}
		return errors.Wrap(errors.CodeInternalError, err, "获取运营商失败")
	}

	carrier.Status = status
	carrier.Updater = currentUserID

	if err := s.carrierStore.Update(ctx, carrier); err != nil {
		return errors.Wrap(errors.CodeInternalError, err, "更新运营商状态失败")
	}

	return nil
}

func (s *Service) toResponse(c *model.Carrier) *dto.CarrierResponse {
	return &dto.CarrierResponse{
		ID:                   c.ID,
		CarrierCode:          c.CarrierCode,
		CarrierName:          c.CarrierName,
		CarrierType:          c.CarrierType,
		Description:          c.Description,
		DataResetDay:         c.DataResetDay,
		RealnameLinkType:     c.RealnameLinkType,
		RealnameLinkTemplate: c.RealnameLinkTemplate,
		Status:               c.Status,
		CreatedAt:            c.CreatedAt.Format(time.RFC3339),
		UpdatedAt:            c.UpdatedAt.Format(time.RFC3339),
	}
}
