"use strict";
const db = require("../../models/index");
const sequelize = require("sequelize");
const Op = sequelize.Op;

const bulkUpsertRealEstates = async realEstateData => {
  try {
    const fieldsToUpdateIfDuplicate = [
      "realEstateType",
      "adType",
      "price",
      "area",
      "streetNumber",
      "streetName",
      "locality",
      "municipality",
      "city",
      "region",
      "entity",
      "country",
      "locationLat",
      "locationLong",
      "title",
      "shortDescription",
      "longDescription",
      "gardenSize",
      "adStatus",
      "updatedAt",
      "renewedDate",
      "numberOfRooms",
      "numberOfFloors",
      "floor",
      "accessRoadType",
      "heatingType",
      "furnishingType",
      "balcony",
      "newBuilding",
      "elevator",
      "water",
      "electricity",
      "drainageSystem",
      "registeredInZkBooks",
      "recentlyAdapted",
      "parking",
      "garage",
      "gas",
      "antiTheftDoor",
      "airCondition",
      "phoneConnection",
      "cableTV",
      "internet",
      "basementAttic",
      "storeRoom",
      "videoSurveillance",
      "alarm",
      "suitableForStudents",
      "includingBills",
      "animalsAllowed",
      "pool",
      "urbanPlanPermit",
      "buildingPermit",
      "utilityConnection",
      "distanceToRiver",
      "numberOfViewsAgency"
    ];
    const order = [["updatedAt", "desc"]];

    return await db.RealEstate.bulkCreate(realEstateData, {
      updateOnDuplicate: fieldsToUpdateIfDuplicate,
      returning: true,
      order
    });
  } catch (e) {
    console.log("Error bulk upserting realEstates : ", e);
  }
};

const getRealEstateById = async id => {
  return db.RealEstate.findByPk(id);
};

const findRealEstatesForSearchRequest = async (searchRequest, maxResults) => {
  const {
    priceMin,
    priceMax,
    sizeMin,
    sizeMax,
    adType,
    realEstateType,
    areaToSearch
  } = searchRequest;

  const longitudeColumn = sequelize.col("locationLong");
  const latitudeColumn = sequelize.col("locationLat");

  const pointGeometry = sequelize.fn(
    "ST_Point",
    longitudeColumn,
    latitudeColumn
  );
  const pointWithSRID = sequelize.fn("ST_SetSRID", pointGeometry, 4326);
  const areaToSearchAsGeometry = sequelize.fn(
    "ST_GeomFromGeoJSON",
    JSON.stringify(areaToSearch)
  );
  const areaToSearchWithSRID = sequelize.fn(
    "ST_SetSRID",
    areaToSearchAsGeometry,
    4326
  );
  const contains = sequelize.fn(
    "ST_Contains",
    areaToSearchWithSRID,
    pointWithSRID
  );

  const geoSearchQueryPart = sequelize.where(contains, true);

  const query = {
    adType,
    realEstateType,
    price: {
      [Op.lte]: priceMax,
      [Op.gte]: priceMin
    },
    area: {
      [Op.lte]: sizeMax,
      [Op.gte]: sizeMin
    },
    [Op.and]: geoSearchQueryPart
  };

  const order = [["updatedAt", "desc"]];

  return await db.RealEstate.findAll({
    where: query,
    limit: maxResults,
    order
  });
};

module.exports = {
  bulkUpsertRealEstates,
  getRealEstateById,
  findRealEstatesForSearchRequest
};
