"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.CreateTokenUseCase = void 0;
const uuid_1 = require("uuid");
const token_1 = require("../../../domain/entities/token");
const not_found_error_1 = require("../../../domain/errors/not-found-error");
const validation_error_1 = require("../../../domain/errors/validation-error");
class CreateTokenUseCase {
    tokenRepository;
    networkRepository;
    imageStorage;
    coinMarketCapClient;
    logger;
    constructor(tokenRepository, networkRepository, imageStorage, coinMarketCapClient, logger) {
        this.tokenRepository = tokenRepository;
        this.networkRepository = networkRepository;
        this.imageStorage = imageStorage;
        this.coinMarketCapClient = coinMarketCapClient;
        this.logger = logger;
    }
    async execute(input) {
        const network = await this.networkRepository.findById(input.networkId);
        if (!network) {
            throw new not_found_error_1.NotFoundError('Network', input.networkId);
        }
        if (!input.isNative && !input.address) {
            throw new validation_error_1.ValidationError('Non-native tokens must have a contract address', {
                address: ['Contract address is required'],
            });
        }
        const id = (0, uuid_1.v4)();
        const thumbnail = input.thumbnail
            ? await this.imageStorage.downloadAndStore('token', id, input.thumbnail, {
                name: input.name,
                symbol: input.symbol,
            })
            : null;
        const info = await this.resolveTokenInfo(input);
        const token = token_1.Token.create(id, input.isNative, input.isNative ? null : (input.address ?? null), input.networkId, thumbnail, input.name, input.symbol, input.decimals, input.code, info, input.isActive, input.minimumSwapValue ?? null, null);
        return this.tokenRepository.save(token);
    }
    async resolveTokenInfo(input) {
        try {
            const coin = input.cmcId
                ? await this.coinMarketCapClient.getCoin(input.cmcId)
                : await this.coinMarketCapClient.getCoinInfoBySlug(input.code);
            if (coin?.description) {
                return coin.description;
            }
        }
        catch (error) {
            this.logger.warn('Failed to fetch token info from CoinMarketCap, using fallback', {
                code: input.code,
                cmcId: input.cmcId,
                error,
            });
        }
        return input.info ?? null;
    }
}
exports.CreateTokenUseCase = CreateTokenUseCase;
//# sourceMappingURL=create-token.use-case.js.map