package ru.yandex.autotests.direct.db.steps;

import java.sql.Timestamp;
import java.util.List;
import java.util.Set;

import javax.util.streamex.StreamEx;

import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.BannerImagesFormatsImageType;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.BannerImagesStatusmoderate;
import ru.yandex.autotests.direct.db.models.jooq.ppc.enums.ImagesStatusmoderate;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannerImagesFormatsRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannerImagesPoolRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.BannerImagesRecord;
import ru.yandex.autotests.direct.db.models.jooq.ppc.tables.records.ImagesRecord;
import ru.yandex.autotests.direct.db.steps.base.BasePpcSteps;
import ru.yandex.qatools.allure.annotations.Step;

import static ru.yandex.autotests.direct.db.models.jooq.ppc.tables.BannerImages.BANNER_IMAGES;
import static ru.yandex.autotests.direct.db.models.jooq.ppc.tables.BannerImagesFormats.BANNER_IMAGES_FORMATS;
import static ru.yandex.autotests.direct.db.models.jooq.ppc.tables.BannerImagesPool.BANNER_IMAGES_POOL;
import static ru.yandex.autotests.direct.db.models.jooq.ppc.tables.Images.IMAGES;

/*
* todo javadoc
*/
public class ImagesSteps extends BasePpcSteps {
    @Deprecated
    @Step("DB: получение записей из banner_images по imageHash: {0}")
    public List<BannerImagesRecord> getBannerImagesRecordsByHash(String imageHash) {
        return exec(db -> db.selectFrom(BANNER_IMAGES)
                .where(BANNER_IMAGES.IMAGE_HASH.eq(imageHash))
                .fetch());
    }

    @Deprecated
    @Step("DB: получение записи из banner_images по bid: {0}")
    public BannerImagesRecord getBannerImagesRecordsByBid(Long bid) {
        return exec(db -> db.selectFrom(BANNER_IMAGES)
                .where(BANNER_IMAGES.BID.eq(bid))
                .fetchOne());
    }

    /**
     * Метод возвращает несколько изображений, записи из таблицы ppc.banner_images по image_hash
     *
     * @param imageHashes массив хешей картинок
     * @return BannerImagesRecord
     */
    @Step("DB: получение нескольких записей из таблицы ppc.banner_images по списку image_hash: [{0}]")
    public List<BannerImagesRecord> getBannerImagesByHash(String... imageHashes) {
        return exec(db -> db.selectFrom(BANNER_IMAGES)
                .where(BANNER_IMAGES.IMAGE_HASH.in(imageHashes))
                .fetch());
    }

    /**
     * Метод возвращает одно изображение, запись из таблицы ppc.banner_images по image_hash
     *
     * @param imageHash хеш картинки
     * @return BannerImagesRecord
     */
    @Step("DB: получение записи из таблицы ppc.banner_images по image_hash: {0}")
    public BannerImagesRecord getBannerImagesByHash(String imageHash) {
        return exec(db -> db.selectFrom(BANNER_IMAGES)
                        .where(BANNER_IMAGES.IMAGE_HASH.eq(imageHash))
                        .fetchOne());
    }

    /**
     * Метод возвращает одно изображение, запись из таблицы ppc.banner_images по bid
     *
     * @param bid id баннера
     * @return BannerImagesRecord
     */
    @Step("DB: получение записи из banner_images по bid: {0}")
    public BannerImagesRecord getBannerImagesByBid(Long bid) {
        return exec(db -> db.selectFrom(BANNER_IMAGES)
                        .where(BANNER_IMAGES.BID.eq(bid))
                        .fetchOne());
    }

    /**
     * Метод возвращает одно изображение, запись из таблицы ppc.banner_images по imageId
     *
     * @param imageId id картинки
     * @return BannerImagesRecord
     */
    @Step("DB: получение записи из banner_images по imageId: {0}")
    public BannerImagesRecord getBannerImages(Long imageId) {
        return exec(db -> db.selectFrom(BANNER_IMAGES)
                .where(BANNER_IMAGES.IMAGE_ID.eq(imageId))
                .fetchOne());
    }

    /**
     * Метод обновляет запись в таблице ppc.banner_images
     *
     * @param bannerImage объект с настройками клиента
     * @return
     */
    @Step("DB: Oбновление записи в таблице ppc.banner_images")
    public void updateBannerImage(BannerImagesRecord bannerImage) {
        run(db -> db.update(BANNER_IMAGES)
                .set(bannerImage)
                .where(BANNER_IMAGES.IMAGE_HASH.eq(bannerImage.getImageHash()))
                .execute()
        );
    }

    @Step("DB: установка statusModerate в таблице banner_images imageHash:{0}")
    public void setBannerImagesStatusModerate(String imageHash, BannerImagesStatusmoderate statusModerate) {
        exec(db -> db.update(BANNER_IMAGES)
                .set(BANNER_IMAGES.STATUSMODERATE, statusModerate)
                .where(BANNER_IMAGES.IMAGE_HASH.eq(imageHash))
                .execute());
    }

    @Step("DB: установка statusModerate в таблице banner_images imageId:{0}")
    public void setBannerImagesStatusModerate(Long imageId, BannerImagesStatusmoderate statusModerate) {
        exec(db -> db.update(BANNER_IMAGES)
                .set(BANNER_IMAGES.STATUSMODERATE, statusModerate)
                .where(BANNER_IMAGES.IMAGE_ID.eq(imageId))
                .execute());
    }

    @Step("DB: установка statusModerate в таблице banner_images по bid:{0}")
    public void setBannerImagesStatusModerateByBid(Long bid, BannerImagesStatusmoderate statusModerate) {
        Long imageId = getBannerImagesByBid(bid).getImageId();
        exec(db -> db.update(BANNER_IMAGES)
                .set(BANNER_IMAGES.STATUSMODERATE, statusModerate)
                .where(BANNER_IMAGES.IMAGE_ID.eq(imageId))
                .execute());
    }

    @Step("DB: выставить время добавления картинки в таблице ppc.banner_images по imageId = {0}, date = {1}")
    public void setBannerImagesDateAdded(Long imageId, Timestamp date) {
        exec(db -> db.update(BANNER_IMAGES)
                .set(BANNER_IMAGES.DATE_ADDED, date)
                .where(BANNER_IMAGES.IMAGE_ID.eq(imageId))
                .execute());
    }

    @Step("DB: выставить bsBannerId = {1} в таблице ppc.banner_images по bid = {0}")
    public void setBannerIdByBid(Long bid, Long bsBannerID) {
        exec(db -> db.update(BANNER_IMAGES)
                .set(BANNER_IMAGES.BANNERID, bsBannerID)
                .where(BANNER_IMAGES.BID.eq(bid))
                .execute());
    }

    @Step("DB: получение записи из banner_images_formats по imageHash {0}")
    public BannerImagesFormatsRecord getBannerImagesFormatsRecords(String imageHash) {
        return exec(db -> db.selectFrom(BANNER_IMAGES_FORMATS)
                .where(BANNER_IMAGES_FORMATS.IMAGE_HASH.eq(imageHash))
                .fetchOne());
    }

    @Step("DB: получение записей из banner_images_formats по imageHash'ам {0}")
    public List<BannerImagesFormatsRecord> getBannerImagesFormatsRecordsForHashes(String... imageHashes) {
        return exec(db -> db.selectFrom(BANNER_IMAGES_FORMATS)
                .where(BANNER_IMAGES_FORMATS.IMAGE_HASH.in(imageHashes))
                .fetch());
    }

    @Step("DB: обновление записи в ppc.banner_images_formats")
    public void updateBannerImagesFormatsRecord(BannerImagesFormatsRecord bannerImagesFormatsRecord) {
        exec(db -> db.update(BANNER_IMAGES_FORMATS)
                .set(bannerImagesFormatsRecord)
                .where(BANNER_IMAGES_FORMATS.IMAGE_HASH.eq(bannerImagesFormatsRecord.getImageHash()))
                .execute());
    }

    @Step("DB: установка image_type в ppc.banner_images_formats")
    public void setImageType(String imageHash, BannerImagesFormatsImageType imageType) {
        exec(db -> db.update(BANNER_IMAGES_FORMATS)
                .set(BANNER_IMAGES_FORMATS.IMAGE_TYPE, imageType)
                .where(BANNER_IMAGES_FORMATS.IMAGE_HASH.eq(imageHash))
                .execute());
    }

    @Step("DB: удаление записи в таблице ppc.banner_images_formats для bid:{0}")
    public void deleteBannerImagesFormatsRecord(String imageHash) {
        exec(db -> db.deleteFrom(BANNER_IMAGES_FORMATS)
                .where(BANNER_IMAGES_FORMATS.IMAGE_HASH.eq(imageHash))
                .execute());
    }

    @Step("DB: получение записей из banner_images_pool по imageHash {0}")
    public List<BannerImagesPoolRecord> getBannerImagesPoolRecords(String imageHash) {
        return exec(db -> db.selectFrom(BANNER_IMAGES_POOL)
                .where(BANNER_IMAGES_POOL.IMAGE_HASH.eq(imageHash))
                .fetch());
    }

    @Step("DB: получение записей из images по imageHash {0}")
    public List<ImagesRecord> getImagesRecords(String imageHash) {
        return exec(db -> db.selectFrom(IMAGES)
                .where(IMAGES.IMAGE_HASH.eq(imageHash))
                .fetch());
    }

    @Step("DB: получение записи из images: imageId={0}")
    public ImagesRecord getImagesRecord(Long imageId) {
        return exec(db -> db.selectFrom(IMAGES)
                .where(IMAGES.IMAGE_ID.eq(imageId))
                .fetchOne());
    }

    @Step("DB: получение записи из images: cid={0}, pid={0}, bid={0}")
    public ImagesRecord getImagesRecords(Long cid, Long pid, Long bid) {
        return exec(db -> db.selectFrom(IMAGES)
                .where(IMAGES.CID.eq(cid).and(IMAGES.PID.eq(pid)).and(IMAGES.BID.eq(bid)))
                .fetchOne());
    }

    @Step("DB: установка statusModerate в таблице images для imageId:{0}, imageHash:{1}")
    public void setImageStatusModerate(Long imageId, ImagesStatusmoderate statusModerate) {
        exec(db -> db.update(IMAGES)
                .set(IMAGES.STATUSMODERATE, statusModerate)
                .where(IMAGES.IMAGE_ID.eq(imageId))
                .execute());
    }

    @Step("DB: установка statusModerate в таблице images для bid:{0}, imageHash:{1}")
    public void setImageStatusModerate(Long bid, String imageHash, ImagesStatusmoderate statusModerate) {
        exec(db -> db.update(IMAGES)
                .set(IMAGES.STATUSMODERATE, statusModerate)
                .where(IMAGES.IMAGE_HASH.eq(imageHash)
                        .and(IMAGES.BID.eq(bid)))
                .execute());
    }

    @Step("DB: установка image_text в таблице images для bid:{0}, imageHash:{1}, imageText:{2}")
    public void setImageText(Long bid, String imageText) {
        exec(db -> db.update(IMAGES)
                .set(IMAGES.IMAGE_TEXT, imageText)
                .where(IMAGES.BID.eq(bid))
                .execute());
    }

    @Step("DB: установка statusModerate в таблице images для cid:{0}, pid:{1}, bid:{2}, imageHash:{3}")
    public void setImageStatusModerate(Long cid, Long pid, Long bid,
                                       String imageHash, ImagesStatusmoderate statusModerate) {
        exec(db -> db.update(IMAGES)
                .set(IMAGES.STATUSMODERATE, statusModerate)
                .where(IMAGES.IMAGE_HASH.eq(imageHash)
                        .and(IMAGES.CID.eq(cid))
                        .and(IMAGES.PID.eq(pid))
                        .and(IMAGES.BID.eq(bid)))
                .execute());
    }

    @Step("DB: новая запись в таблице images")
    public void saveImage(ImagesRecord imagesRecord) {
        exec(db -> db.insertInto(IMAGES)
                .set(imagesRecord.setImageId(autoIncSteps().getNewImageId()))
                .execute());
    }

    @Step("DB: удаление записи в таблице images для bid:{0}")
    public void deleteImage(Long bid) {
        exec(db -> db.deleteFrom(IMAGES)
                .where(IMAGES.BID.eq(bid))
                .execute());
    }

    @Step("DB: удаление записи в таблице images для cid:{0}, pid:{1}, bid:{2}")
    public void deleteImage(Long cid, Long pid, Long bid) {
        exec(db -> db.deleteFrom(IMAGES)
                .where(IMAGES.CID.eq(cid)
                        .and(IMAGES.PID.eq(pid))
                        .and(IMAGES.BID.eq(bid)))
                .execute());
    }

    @Step("DB: установка mds_meta в таблице banner_images_formats для imageHash:{0}")
    public void setImageMdsMeta(String imageHash, String mdsMeta) {
        exec(db -> db.update(BANNER_IMAGES_FORMATS)
                .set(BANNER_IMAGES_FORMATS.MDS_META, mdsMeta)
                .where(BANNER_IMAGES_FORMATS.IMAGE_HASH.eq(imageHash))
                .execute());
    }

    @Step("DB: установка mds_meta_user_override в таблице banner_images_pool для ClientId:{0}, imageHash:{1}")
    public void setImageMdsMetaUserOverride(long ClientID, String imageHash, String mdsMetaUserOverride) {
        exec(db -> db.update(BANNER_IMAGES_POOL)
                .set(BANNER_IMAGES_POOL.MDS_META_USER_OVERRIDE, mdsMetaUserOverride)
                .where(BANNER_IMAGES_POOL.IMAGE_HASH.eq(imageHash)
                        .and(BANNER_IMAGES_POOL.CLIENTID.eq(ClientID)))
                .execute());
    }

    @Step("DB: установка opts в таблице banner_images для bid:{1}")
    public void setImageOpts(Long bid,
                             Set<JooqBannerImagesOpts> jooqBannerImagesOpts) {
        String opts = StreamEx.of(jooqBannerImagesOpts)
                .map(JooqBannerImagesOpts::dbValue)
                .joining(",");

        exec(db -> db.update(BANNER_IMAGES)
                .set(BANNER_IMAGES.OPTS, opts)
                .where(BANNER_IMAGES.BID.eq(bid))
                .execute());
    }
}
