package chainassetsdb

import (
	ri "github.com/tech/sendico/pkg/db/repository/index"
	"github.com/tech/sendico/pkg/db/template"
	"github.com/tech/sendico/pkg/mlogger"
	"github.com/tech/sendico/pkg/model"
	"github.com/tech/sendico/pkg/mservice"
	"go.mongodb.org/mongo-driver/v2/mongo"
	"go.uber.org/zap"
)

type ChainAssetsDB struct {
	template.DBImp[*model.ChainAssetDescription]
}

func Create(logger mlogger.Logger, db *mongo.Database) (*ChainAssetsDB, error) {
	p := &ChainAssetsDB{
		DBImp: *template.Create[*model.ChainAssetDescription](logger, mservice.ChainAssets, db),
	}

	// 1) Canonical lookup: enforce single (chain, tokenSymbol)
	if err := p.Repository.CreateIndex(&ri.Definition{
		Name:   "idx_chain_symbol",
		Unique: true,
		Keys: []ri.Key{
			{Field: "asset.chain", Sort: ri.Asc},
			{Field: "asset.tokenSymbol", Sort: ri.Asc},
		},
	}); err != nil {
		p.Logger.Error("Failed index (chain, symbol) unique", zap.Error(err))
		return nil, err
	}

	// 2) Prevent duplicate contracts inside the same chain, but only when contract exists
	if err := p.Repository.CreateIndex(&ri.Definition{
		Name:   "idx_chain_contract_unique",
		Unique: true,
		Sparse: true,
		Keys: []ri.Key{
			{Field: "asset.chain", Sort: ri.Asc},
			{Field: "asset.contractAddress", Sort: ri.Asc},
		},
	}); err != nil {
		p.Logger.Error("Failed index (chain, contract) unique", zap.Error(err))
		return nil, err
	}

	// 3) Fast contract lookup, skip docs without contractAddress (native assets)
	if err := p.Repository.CreateIndex(&ri.Definition{
		Name:   "idx_contract_lookup",
		Sparse: true,
		Keys: []ri.Key{
			{Field: "asset.contractAddress", Sort: ri.Asc},
		},
	}); err != nil {
		p.Logger.Error("Failed index contract lookup", zap.Error(err))
		return nil, err
	}

	// 4) List assets per chain
	if err := p.Repository.CreateIndex(&ri.Definition{
		Name: "idx_chain_list",
		Keys: []ri.Key{
			{Field: "asset.chain", Sort: ri.Asc},
		},
	}); err != nil {
		p.Logger.Error("Failed index chain list", zap.Error(err))
		return nil, err
	}

	return p, nil
}
