package example

import (
	"context"

	"kra/internal/biz/example"
	"kra/internal/data/model"
	"kra/internal/data/query"

	"gorm.io/gorm"
)

type customerRepo struct {
	db *gorm.DB
}

// NewCustomerRepo 创建客户仓储
func NewCustomerRepo(db *gorm.DB) example.CustomerRepo {
	return &customerRepo{db: db}
}

func (r *customerRepo) Create(ctx context.Context, customer *example.Customer) error {
	m := toCustomerModel(customer)
	return r.db.WithContext(ctx).Create(m).Error
}

func (r *customerRepo) Update(ctx context.Context, customer *example.Customer) error {
	return r.db.WithContext(ctx).Save(toCustomerModel(customer)).Error
}

func (r *customerRepo) Delete(ctx context.Context, id uint) error {
	return r.db.WithContext(ctx).Delete(&model.ExaCustomer{}, id).Error
}

func (r *customerRepo) FindByID(ctx context.Context, id uint) (*example.Customer, error) {
	c := query.ExaCustomer
	m, err := c.WithContext(ctx).Where(c.ID.Eq(int64(id))).First()
	if err != nil {
		return nil, err
	}
	return toCustomerBiz(m), nil
}

func (r *customerRepo) List(ctx context.Context, authorityIds []uint, page, pageSize int) ([]*example.Customer, int64, error) {
	c := query.ExaCustomer
	q := c.WithContext(ctx)

	if len(authorityIds) > 0 {
		ids := make([]int64, len(authorityIds))
		for i, id := range authorityIds {
			ids[i] = int64(id)
		}
		q = q.Where(c.SysUserAuthorityID.In(ids...))
	}

	total, err := q.Count()
	if err != nil {
		return nil, 0, err
	}

	offset := (page - 1) * pageSize
	list, err := q.Offset(offset).Limit(pageSize).Find()
	if err != nil {
		return nil, 0, err
	}

	result := make([]*example.Customer, len(list))
	for i, m := range list {
		result[i] = toCustomerBiz(m)
	}
	return result, total, nil
}

// 转换函数
func toCustomerModel(c *example.Customer) *model.ExaCustomer {
	return &model.ExaCustomer{
		ID:                 int64(c.ID),
		CustomerName:       c.CustomerName,
		CustomerPhoneData:  c.CustomerPhoneData,
		SysUserID:          int64(c.SysUserID),
		SysUserAuthorityID: int64(c.SysUserAuthorityID),
	}
}

func toCustomerBiz(m *model.ExaCustomer) *example.Customer {
	return &example.Customer{
		ID:                 uint(m.ID),
		CustomerName:       m.CustomerName,
		CustomerPhoneData:  m.CustomerPhoneData,
		SysUserID:          uint(m.SysUserID),
		SysUserAuthorityID: uint(m.SysUserAuthorityID),
		CreatedAt:          m.CreatedAt,
		UpdatedAt:          m.UpdatedAt,
	}
}
