import {Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges} from '@angular/core';
import {
Address,
AppUtil,
DialogResponseType,
NewCompleteProperty,
NewProperty,
PFile,
PFileTypeEnum,
PropertyInfo,
PropertyTypeEnum,
StatusTypeEnum,
UserMedia
} from '@maplander/types';
import {SnackBarService} from '@maplander/core';
import {EditorComponent} from '../editor/editor.component';
import {OwnerInfoComponent} from '../owner-info/owner-info.component';
import {DocumentsComponent} from '../documents/documents.component';
import {MultimediaUploaderService} from '../multimedia-uploader/multimedia-uploader.service';
import {AnnounceConfirmService} from '../announce-confirm/announce-confirm.service';
import {DocumentVisorService} from '../../../document-visor/document-visor.service';
import {Utils} from '../../../../utils';
import {ShareService} from '@maplander/shared';
import {GalleryService} from '../gallery/gallery.service';
export enum PropertyEventType {
CREATE = 'CREATE',
UPDATE = 'UPDATE',
ANNOUNCE = 'ANNOUNCE',
HIDE = 'HIDE',
SHOW = 'SHOW',
ADDRESS = 'ADDRESS',
REAL_ESTATE_EXCHANGE = 'REAL_ESTATE_EXCHANGE',
SHARE_COMMISSION = 'SHARE_COMMISSION',
BROCHURE = 'BROCHURE',
POSTER = 'POSTER',
BACK = 'BACK'
}
export interface PropertyEventChange {
type: PropertyEventType;
payload?: any;
}
@Component({
selector: 'lib-property',
templateUrl: './property.component.html',
styleUrls: ['./property.component.scss']
})
export class PropertyComponent implements OnInit, OnChanges {
@Input() property: NewCompleteProperty;
@Input() utils: AppUtil;
@Input() propertyType: PropertyTypeEnum;
@Input() mode: 'detail' | 'record' | 'add';
@Input() sharedProperty: { isShared: boolean, ownerAvailable: boolean } = {isShared: false, ownerAvailable: true};
@Input() address: Address;
@Input() mlsLabel: string;
@Input() disableShareCommission: boolean;
@Input() disableConfirmAnnounce: boolean;
@Input() currencyConverted: { currency: string, price: number };
@Input() hideRequestCommission: boolean;
@Output() change: EventEmitter<PropertyEventChange>;
@Output() modeChange: EventEmitter<'detail' | 'record' | 'add'>;
public multimedia: PFile[];
public currentIndex: number;
public frontImageError: boolean;
public currentType: PFileTypeEnum;
public multimediaCount: {
images: number,
images360: number,
videos: number
};
public completeProperty: NewCompleteProperty;
private _allMultimedia: PFile[];
private _newMedia: UserMedia[];
private _editorInstance: EditorComponent;
private _ownerInstance: OwnerInfoComponent;
private _documentsInstance: DocumentsComponent;
constructor(
private _uploaderService: MultimediaUploaderService,
private _announceService: AnnounceConfirmService,
private _snackBar: SnackBarService,
private _share: ShareService,
private _gallery: GalleryService,
private _documentService: DocumentVisorService
) {
this.initCompleteProperty();
this.change = new EventEmitter<PropertyEventChange>();
this.modeChange = new EventEmitter<'detail' | 'record' | 'add'>();
this.disableShareCommission = false;
this.disableConfirmAnnounce = false;
this.currentIndex = 0;
this.multimedia = [];
this._allMultimedia = [];
this._newMedia = [];
this.multimediaCount = {
images: 0,
images360: 0,
videos: 0
};
this.currentType = PFileTypeEnum.IMAGE;
}
ngOnInit() {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['property'] && changes['property'].currentValue) {
this.completeProperty = new NewCompleteProperty(changes['property'].currentValue || null);
this.parseMultimedia();
this.assignMultimediaByType();
this.validateMultimediaTypeCount();
}
}
saveData(): void {
this.restoreFrontImageError();
if (this._editorInstance.validateFormInvalid()) {
return;
}
this.parseDataByComponents();
this.change.emit({
type: this.completeProperty.property.id ? PropertyEventType.UPDATE : PropertyEventType.CREATE,
payload: {
property: this.completeProperty,
newMedia: this._newMedia
}
});
}
agentActions(type: any): void {
this.change.emit({
type: type as PropertyEventType,
payload: {property: this.completeProperty, newMedia: this._newMedia}
});
}
shareProperty(): void {
this._share.open(this.completeProperty.property.url);
}
openGallery(): void {
if (this._allMultimedia.length === 0) {
return;
}
let type = null;
if (this.multimedia.length > 0) {
type = this.multimedia[0].type;
}
this._gallery.open(this._allMultimedia, this.currentIndex, type);
}
goToEditProperty(): void {
this.mode = 'add';
this.modeChange.emit(this.mode);
}
goToBack(): void {
this.restoreFrontImageError();
this.change.emit({
type: PropertyEventType.BACK
});
}
goToUpdateVisibility(): void {
this.change.emit({
type: this.completeProperty.property.status === StatusTypeEnum.ANNOUNCED ? PropertyEventType.HIDE : PropertyEventType.SHOW,
payload: {property: this.completeProperty, newMedia: this._newMedia}
});
}
goToPublish(): void {
if (this.mode === 'add') {
this.parseDataByComponents();
}
const errors = Utils.getErrorsForPublish(this.completeProperty.property);
if (errors.length > 0) {
this.mode = 'add';
this.modeChange.emit(this.mode);
setTimeout(() => {
this.validateFrontImageOnErrors(errors);
this._editorInstance.setErrorsOnFields(errors);
}, 200);
this._snackBar.setMessage('Complete los campos faltantes para poder publicar', 'OK', 5000, 'left', 'bottom');
} else {
if (this.disableConfirmAnnounce) {
this.change.emit({
type: PropertyEventType.ANNOUNCE,
payload: {property: this.completeProperty, newMedia: this._newMedia}
});
return;
}
this._announceService.open().afterClosed().subscribe((response) => {
if (response.code === DialogResponseType.ACCEPT) {
this.change.emit({
type: PropertyEventType.ANNOUNCE,
payload: {property: this.completeProperty, newMedia: this._newMedia}
});
}
});
}
}
onMultimediaIndexChanged(ev: number): void {
this.currentIndex = ev;
}
changeMultimediaType(type: string): void {
this.currentType = type as PFileTypeEnum;
this.assignMultimediaByType();
}
openUploaderMultimedia(): void {
this._uploaderService.open(this.currentType, this._allMultimedia, this._newMedia).afterClosed().subscribe((response) => {
if (response) {
this._newMedia = response.newMedia || [];
this._allMultimedia = Object.assign([], response.multimedia || []);
this.assignFrontImage();
this.assignMultimediaByType();
this.validateMultimediaTypeCount();
}
});
}
onEditorInstance(ev: EditorComponent): void {
this._editorInstance = ev;
}
onOwnerInstance(ev: OwnerInfoComponent): void {
this._ownerInstance = ev;
}
onDocumentsInstance(ev: DocumentsComponent): void {
this._documentsInstance = ev;
}
onSelectAddress(): void {
this.change.emit({
type: PropertyEventType.ADDRESS
});
}
private restoreFrontImageError(): void {
this.frontImageError = false;
}
private parseMultimedia(): void {
this._allMultimedia = [];
this._allMultimedia = this._allMultimedia.concat(this.completeProperty.images || []);
this._allMultimedia = this._allMultimedia.concat(this.completeProperty.videos || []);
this._allMultimedia = this._allMultimedia.concat(this.completeProperty.spherics || []);
}
private getMultimediaByType(type: PFileTypeEnum): PFile[] {
const response = [];
this._allMultimedia.forEach(item => {
if (item.type === type) {
response.push(item);
}
});
return response;
}
private assignFrontImage(): void {
const images: PFile[] = [];
this._allMultimedia.forEach(multimedia => {
if (multimedia.type === PFileTypeEnum.IMAGE) {
images.push(multimedia);
}
});
if (images.length > 0) {
this.completeProperty.property.image = images[0].fileCS.thumbnail;
this.frontImageError = false;
} else {
this.completeProperty.property.image = null;
}
this.completeProperty = new NewCompleteProperty(this.completeProperty);
}
private assignMultimediaByType(): void {
const response = [];
this._allMultimedia.forEach(item => {
if (item.type === this.currentType) {
response.push(item);
}
});
this.multimedia = Object.assign([], response);
}
private validateFrontImageOnErrors(errors: string[]): void {
errors.forEach(error => {
if (error === 'image') {
this.frontImageError = true;
}
});
}
private validateMultimediaTypeCount(): void {
this.multimediaCount.images = 0;
this.multimediaCount.images360 = 0;
this.multimediaCount.videos = 0;
this._allMultimedia.forEach(item => {
switch (item.type) {
case PFileTypeEnum.IMAGE:
this.multimediaCount.images++;
break;
case PFileTypeEnum.SPHERIC:
this.multimediaCount.images360++;
break;
case PFileTypeEnum.VIDEO:
this.multimediaCount.videos++;
break;
}
});
}
private parseDataByComponents(): void {
this.completeProperty.property = this._editorInstance.getProperty();
this.completeProperty.property.propertyInfo.owner = this._ownerInstance.getOwner();
const documentsResponse = this._documentsInstance.getDocuments();
this.completeProperty.files = documentsResponse.documents;
this._newMedia = this._newMedia.concat(documentsResponse.newMedia);
this.completeProperty.images = this.getMultimediaByType(PFileTypeEnum.IMAGE);
this.completeProperty.spherics = this.getMultimediaByType(PFileTypeEnum.SPHERIC);
this.completeProperty.videos = this.getMultimediaByType(PFileTypeEnum.VIDEO);
}
private initCompleteProperty(): void {
const complete = new NewCompleteProperty();
complete.property = new NewProperty();
complete.property.propertyInfo = new PropertyInfo();
this.completeProperty = complete;
}
}