package ru.yandex.webmaster3.storage.greenurls;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import lombok.Builder;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.tuple.Pair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Repository;

import ru.yandex.webmaster3.core.data.WebmasterHostId;
import ru.yandex.webmaster3.storage.clickhouse.ClickhouseTableInfo;
import ru.yandex.webmaster3.storage.clickhouse.TableProvider;
import ru.yandex.webmaster3.storage.clickhouse.TableType;
import ru.yandex.webmaster3.storage.util.clickhouse2.AbstractClickhouseDao;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHPrimitiveType;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHRow;
import ru.yandex.webmaster3.storage.util.clickhouse2.CHTable;
import ru.yandex.webmaster3.storage.util.clickhouse2.ClickhouseServer;
import ru.yandex.webmaster3.storage.util.clickhouse2.query.QueryBuilder;

@Repository
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class CurrentSerpDataCHDao extends AbstractClickhouseDao {
    private static final String TABLE_NAME = "current_serp_data";
    private static final List<String> FIELDS = List.of(F.HOST_ID, F.GREEN_URLS_CNT, F.QA_URLS_CNT);

    private static final Map<String, BuilderMapper<SerpDataRecord.SerpDataRecordBuilder, ?>> MAPPERS = Stream.of(
            BuilderMapper.of(F.HOST_ID, CHRow::getHostId,
                    SerpDataRecord.SerpDataRecordBuilder::hostId),
            BuilderMapper.of(F.GREEN_URLS_CNT, CHRow::getLong, SerpDataRecord.SerpDataRecordBuilder::greenUrlsCnt),
            BuilderMapper.of(F.QA_URLS_CNT, CHRow::getLong, SerpDataRecord.SerpDataRecordBuilder::qaUrlsCnt)
    ).collect(Collectors.toUnmodifiableMap(BuilderMapper::getName, Function.identity()));

    public static final CHTable TABLE = CHTable.builder()
            .database(AbstractClickhouseDao.DB_WEBMASTER3_SEARCHURLS)
            .name(TABLE_NAME + "_%s")
            .sharded(false)
            .partitionBy("")
            .keyField(F.HOST_ID, CHPrimitiveType.String)
            .field(F.GREEN_URLS_CNT, CHPrimitiveType.Int64)
            .field(F.QA_URLS_CNT, CHPrimitiveType.Int64)
            .build();

    @Qualifier("legacyMdbTableStorage")
    private final TableProvider tableProvider;
    @Qualifier("legacyMdbClickhouseServer")
    private final ClickhouseServer clickhouseServer;

    @Override
    public ClickhouseServer getClickhouseServer() {
        return clickhouseServer;
    }

    public Pair<Long, Long> getGreenUrlsAndQAUrlsCount(WebmasterHostId hostId) {
        ClickhouseTableInfo table = tableProvider.getTable(TableType.CURRENT_SERP_DATA);
        log.info("sourcePath - {}", table.getSourcePath());
        var query = QueryBuilder.select(FIELDS).from(table.getLocalTableName())
                .where(QueryBuilder.eq(F.HOST_ID, hostId));
        return getClickhouseServer().queryOne(table.chContext(getClickhouseServer(), hostId), query, chRow -> {
            var builder = SerpDataRecord.builder();
            for (String field : FIELDS) {
                MAPPERS.get(field).apply(chRow, builder);
            }
            var built = builder.build();
            return Pair.of(built.greenUrlsCnt, built.qaUrlsCnt);
        }).orElse(Pair.of(0L, 0L));
    }

    @Value
    @Builder(toBuilder = true)
    public static class SerpDataRecord {
        WebmasterHostId hostId;
        Long greenUrlsCnt;
        Long qaUrlsCnt;
    }

    public static class F {
        public static final String HOST_ID = "host_id";
        public static final String GREEN_URLS_CNT = "green_urls_cnt";
        public static final String QA_URLS_CNT = "qa_urls_cnt";
    }
}
