import ItemHTML from './ItemHTML.js';
import Locations from './Locations.js';
export default class Item {
static NAME_SELECTOR = '.item-link';
static DESCRIPTION_SELECTOR = '.item-description';
static PRICE_SELECTOR = '.item-price';
static GARAGE_SELECTOR = '.item-parking';
static ROOM_SELECTOR = '.item-detail-char .item-detail:nth-child(1)';
static METERS_SELECTOR = '.item-detail-char .item-detail:nth-child(2)';
static ADDITIONAL_INFORMATION_SELECTOR = '.item-detail-char .item-detail:nth-child(3)';
constructor(htmlNode) {
this._node = htmlNode;
this.name = this._extractName();
this.description = this._extractDescription();
this.locationName = this._extractLocationName();
this.price = this._extractPrice();
this.meters = this._extractMeters();
this.priceMeter = this._extractPriceMeter();
this.additionalInfo = this._extractAdditionalInfo();
this.hasGarage = this._extractGarage();
this.hasLift = this._extractLift();
this.isNoLift = this._extractIsNoLift();
this.isExterior = this._extractExterior();
this.isInterior = this._extractInterior();
}
get _data() {
return this._node.nextElementSibling;
}
async extractAsyncData() {
this.location = await this._extractLocation();
this.refreshData();
}
refreshData() {
this.removeData();
this.addData();
}
isDataRendered() {
const nextElement = this._data;
return nextElement.className
&& nextElement.className.includes(ItemHTML.CONTAINER_CLASS_NAME);
}
isProperPrice(price) {
return this.price <= price;
}
isProperPriceMeter(priceMeter) {
return this.priceMeter <= priceMeter;
}
removeData() {
if (!this.isDataRendered()) return;
this._data.remove();
}
addData() {
this._node.insertAdjacentHTML('afterend', ItemHTML.createInformation(this));
}
isFlat() {
return this._nameIncludes('Piso');
}
isHouse() {
return this._nameIncludes('Casa')
|| this._nameIncludes('Chalet')
|| this._nameIncludes('Finca');
}
// TODO: This may be included in isFlat.
isGround() {
return this._nameIncludes('Bajo');
}
_nameIncludes(name) {
return this.name.toLowerCase().includes(name.toLowerCase());
}
_descriptionIncludes(description) {
return this.description.toLowerCase().includes(description.toLowerCase());
}
_extractName() {
return this._node.querySelector(Item.NAME_SELECTOR).textContent;
}
_extractDescription() {
return this._node.querySelector(Item.DESCRIPTION_SELECTOR).textContent;
}
_extractLocationName() {
if (this.name.lastIndexOf(',') != -1) {
return this.name
.substring(this.name.lastIndexOf(','), this.name.length)
.replaceAll('\n', '').replaceAll('.', '')
.replaceAll(',', '').replaceAll(' ', '');
}
return this.name
.substring(this.name.lastIndexOf(' en ') + ' en '.length, this.name.length)
.replaceAll('\n', '').replaceAll('.', '')
.replaceAll(' ', '');
}
async _extractLocation() {
return Locations.get(this.locationName);
}
_extractPrice() {
const priceText = this._node.querySelector(Item.PRICE_SELECTOR).textContent;
return Number(priceText.replace('€', '').replaceAll('.', '').replaceAll(',', ''));
}
_extractMeters() {
let metersNode = this._node.querySelector(Item.METERS_SELECTOR);
let metersText;
if (!metersNode || !metersNode.textContent.includes('m²')) {
metersText = this._node.querySelector(Item.ROOM_SELECTOR).textContent;
} else {
metersText = metersNode.textContent;
}
return Number(metersText
.replace('m²', '')
.replaceAll('.', '')
);
}
_extractPriceMeter() {
return Math.round(this.price / this.meters);
}
_extractAdditionalInfo() {
let additionalInfo = this._node.querySelector(Item.ADDITIONAL_INFORMATION_SELECTOR);
if (!additionalInfo) {
additionalInfo = this._node.querySelector(Item.METERS_SELECTOR);
}
if (!additionalInfo) return null;
return additionalInfo.textContent;
}
_extractLift() {
if (!this.additionalInfo) return false;
return this.additionalInfo.includes('con ascensor');
}
_extractIsNoLift() {
if (!this.additionalInfo) return false;
return this.additionalInfo.includes('sin ascensor');
}
_extractExterior() {
const text = 'exterior';
if (this.additionalInfo && this.additionalInfo.includes(text)) return true;
if (this._descriptionIncludes(text)) return true;
return false;
}
_extractInterior() {
const text = 'interior';
if (this.additionalInfo && this.additionalInfo.includes(text)) return true;
if (this._descriptionIncludes(text)) return true;
return false;
}
_extractGarage() {
return this._node.querySelector(Item.GARAGE_SELECTOR) !== null;
}
}