package ru.yandex.webmaster3.worker.video;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.collect.Range;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import ru.yandex.webmaster3.core.WebmasterException;
import ru.yandex.webmaster3.core.http.WebmasterErrorResponse;
import ru.yandex.webmaster3.core.util.IdUtils;
import ru.yandex.webmaster3.core.util.WwwUtil;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskState;
import ru.yandex.webmaster3.core.worker.task.PeriodicTaskType;
import ru.yandex.webmaster3.core.worker.task.TaskResult;
import ru.yandex.webmaster3.storage.util.yt.*;
import ru.yandex.webmaster3.storage.video.OfferErrorType;
import ru.yandex.webmaster3.storage.video.OfferStatus;
import ru.yandex.webmaster3.storage.video.VideohostOffer;
import ru.yandex.webmaster3.storage.video.VideohostOfferService;
import ru.yandex.webmaster3.worker.PeriodicTask;
import ru.yandex.webmaster3.worker.TaskSchedule;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @author vsedaikina
 * 21.10.21
 */
@Slf4j
@RequiredArgsConstructor(onConstructor_ = @Autowired)
@Component
public class ImportVideohostOffersStatusPeriodicTask extends PeriodicTask<ImportVideohostOffersStatusPeriodicTask.TaskState> {
    private final YtService ytService;
    private final VideohostOfferService videohostOfferService;

    @Value("${webmaster3.worker.video.import.current.offers.results.path}")
    private final YtPath tableOffersResults;

    @Override
    public Result run(UUID runId) throws Exception {
        log.info("Read updated videohosting offers statuses");
        ytService.withoutTransaction(cypressService -> {
            AsyncTableReader<YtRow> tableReader = new AsyncTableReader<>(
                    cypressService, tableOffersResults, Range.all(),
                    YtTableReadDriver.createYSONDriver(YtRow.class)
            );

            try (AsyncTableReader.TableIterator<YtRow> iterator = tableReader.read()) {
                List<VideohostOffer> offers = new ArrayList<>();
                while (iterator.hasNext()) {
                    YtRow row = iterator.next();
                    OfferStatus status = OfferStatus.valueOf(row.status);
                    String domainUrl = WwwUtil.cutWWWAndM(IdUtils.urlToHostId(row.hostUrl));

                    if (videohostOfferService.isDomainInWebmaster(domainUrl)) { //add isInExp?
                        offers.add(VideohostOffer.builder()
                                    .hostUrl(domainUrl)
                                    .offerUrl(row.offerUrl)
                                    .status(status)
                                    .addDate(new DateTime(row.addDate))
                                    .error((status == OfferStatus.FAILED) ? OfferErrorType.INVALID_OFFER : OfferErrorType.EMPTY)
                                    .comments(row.comments).build()
                        );
                    }
                }

                log.info("Update statuses in currentYDao");
                videohostOfferService.updateVideohostOffersStatus(offers);
            } catch (YtException | InterruptedException | IOException e) {
                throw new WebmasterException("Error reading Yt table",
                        new WebmasterErrorResponse.YTServiceErrorResponse(getClass(), e), e);
            }

            return true;
        });

        return new Result(TaskResult.SUCCESS);
    }

    @Override
    public PeriodicTaskType getType() {
        return PeriodicTaskType.UPDATE_VIDEOHOST_OFFER_STATUS;
    }

    @Override
    public TaskSchedule getSchedule() {
        return TaskSchedule.startByCron("0 1 * * * *");
    }

    public static class TaskState implements PeriodicTaskState {
    }

    public static class YtRow {
        @JsonProperty("HostUrl")
        private final String hostUrl;
        @JsonProperty("OfferUrl")
        private final String offerUrl;
        @JsonProperty("Status")
        private final String status;
        @JsonProperty("Comments")
        private final String comments;
        @JsonProperty("AddDate")
        private final long addDate;

        @JsonCreator
        public YtRow(String hostUrl, String offerUrl, String status, String comments, long addDate) {
            this.hostUrl = hostUrl;
            this.offerUrl = offerUrl;
            this.status = status;
            this.comments = comments;
            this.addDate = addDate;
        }
    }
}
