import {Component, EventEmitter, OnInit, Output, ViewChild} from '@angular/core';
import {FormComponent} from '../../../../components/form-component';
import {NgForm} from '@angular/forms';
import {IUser} from '../../../../model/entities/user';
import {IMeetingType} from '../../../../model/entities/meeting-type';
import {IConfig} from '../../../../model/virtual/config';
import {AppService} from '../../../../services/app.service';
import {ScrollToService} from '@nicky-lenaers/ngx-scroll-to';
import {Factory} from '../../../../factory/factory';
import {Utils} from '../../../../utils/utils';
import {isNull} from 'util';
import {IService} from '../../../../model/entities/service';
import {IServiceMeeting} from '../../../../model/entities/service-meeting';
import {IServiceContact} from '../../../../model/entities/service-contact';

@Component({
  selector: 'app-service-meeting-edit',
  templateUrl: './service-meeting-edit.component.html',
  styleUrls: ['./service-meeting-edit.component.scss']
})

export class ServiceMeetingEditComponent extends FormComponent implements OnInit {

    @Output() createMeeting: EventEmitter<IServiceMeeting> = new EventEmitter<IServiceMeeting>();
    @Output() editMeeting: EventEmitter<IServiceMeeting> = new EventEmitter<IServiceMeeting>();
    @ViewChild('serviceMeetingForm', { static: true }) serviceMeetingForm: NgForm;

    public service: IService;
    public serviceMeeting: IServiceMeeting;
    public serviceContacts: IServiceContact[];
    public serviceContactsById: {};
    public isExistingServiceContact: boolean;
    public users: IUser[];
    public usersById: {};
    public possibleOwners: IUser[];
    public participants: IUser[];
    public selectedParticipantsById: {};
    public selectedParticipantsByIdInitial: {};
    public owner: IUser;
    public startDate: string;
    public timeStart: string;
    public timeEnd: string;
    public meetingTypes: IMeetingType[];
    public contactPersonValue: string;
    public config: IConfig;

    constructor(public appService: AppService, protected scrollToService: ScrollToService) {
        super(scrollToService);
    }

    ngOnInit() {
        this.config = this.appService.getConfig();
        this.service = Factory.getEmptyService();
        this.serviceMeeting = Factory.getEmptyServiceMeeting();
        this.serviceContacts = [];
        this.serviceContactsById = {};
        this.isExistingServiceContact = false;
        this.users = [];
        this.usersById = {};
        this.possibleOwners = [];
        this.participants = [];
        this.selectedParticipantsById = {};
        this.selectedParticipantsByIdInitial = {};
        this.owner = Factory.getEmptyUser();
        this.startDate = '';
        this.timeStart = '';
        this.timeEnd = '';
        this.meetingTypes = [];
        this.contactPersonValue = '';
    }

    /**
     * Sets data
     * @param service
     * @param serviceMeeting
     * @param isCreationMode
     */
    public setData(service: IService, serviceMeeting: IServiceMeeting, isCreationMode: boolean = false): void {
        this.service = service;
        this.serviceMeeting = serviceMeeting;
        this.serviceContacts = this.service.v_service_contacts;
        this.serviceContactsById = Utils.getSortedObjFromArray(this.serviceContacts, 'id');
        this.users = this.appService.getConfig().users;
        this.isCreationMode = isCreationMode;
        this.owner = this.serviceMeeting.owner_user_id !== null ?
            this.appService.getConfig().vc_user_by_id[this.serviceMeeting.owner_user_id] : null;
        this.startDate = Utils.getDateTimeToDisplay(this.serviceMeeting.start_date, true, false, false, true);
        this.timeStart = Utils.getDateTimeToDisplay(this.serviceMeeting.start_date, false, true);
        this.timeEnd = Utils.getDateTimeToDisplay(this.serviceMeeting.end_date, false, true);
        this.meetingTypes = this.appService.getConfig().meeting_types;
        this.usersById = Utils.getSortedObjFromArray(this.appService.getConfig().users, 'id');
        this.selectedParticipantsById = Utils.getSortedObjFromArray(this.serviceMeeting.v_participants, 'participant_user_id');
        this.selectedParticipantsByIdInitial = Utils.getSortedObjFromArray(this.serviceMeeting.v_participants, 'participant_user_id');
        this.participants = [];
        for (const p in this.usersById) {
            if (this.isCreationMode) {
                // New meeting
                if (this.usersById[p].active) {
                    this.participants.push(this.usersById[p]);
                    this.possibleOwners.push(this.usersById[p]);
                }
            } else {
                // Existing meeting
                const userAttendsToMeeting: boolean = this.selectedParticipantsByIdInitial.hasOwnProperty(this.usersById[p].id);
                if (this.usersById[p].id !== this.owner.id && (this.usersById[p].active || userAttendsToMeeting)) {
                    this.participants.push(this.usersById[p]);
                    this.possibleOwners.push(this.usersById[p]);
                }
                if (this.usersById[p].id === this.owner.id) {
                    this.possibleOwners.push(this.usersById[p]);
                }
            }
        }
        if (isNull(this.serviceMeeting.service_contact_id)) {
            this.serviceMeeting.service_contact_id = -1;
        }
        if (this.serviceMeeting.service_contact_id > 0) {
            this.isExistingServiceContact = true;
        }
        this.errorMsg = '';
        this.resetFormValidation();
    }

    /**
     * On select contact
     * @param e
     */
    public selectContact(e: any) {
        this.serviceMeeting.service_contact_id = e.target.value;
        this.isExistingServiceContact = false;
        this.serviceMeeting.gender = null;
        this.serviceMeeting.firstname = null;
        this.serviceMeeting.lastname = null;
        this.serviceMeeting.department = null;
        this.serviceMeeting.email = null;
        this.serviceMeeting.phone_no = null;
        this.serviceMeeting.mobile_no = null;
        if (this.serviceMeeting.service_contact_id > 0) {
            this.serviceMeeting.gender = this.serviceContactsById[this.serviceMeeting.service_contact_id].gender;
            this.serviceMeeting.firstname = this.serviceContactsById[this.serviceMeeting.service_contact_id].firstname;
            this.serviceMeeting.lastname = this.serviceContactsById[this.serviceMeeting.service_contact_id].lastname;
            this.serviceMeeting.department = this.serviceContactsById[this.serviceMeeting.service_contact_id].department;
            this.serviceMeeting.email = this.serviceContactsById[this.serviceMeeting.service_contact_id].email;
            this.serviceMeeting.phone_no = this.serviceContactsById[this.serviceMeeting.service_contact_id].phone_no;
            this.serviceMeeting.mobile_no = this.serviceContactsById[this.serviceMeeting.service_contact_id].mobile_no;
            this.isExistingServiceContact = true;
        }
    }

    /**
     * On select owner
     * @param e
     */
    public selectOwner(e: any) {
        if (e.target.value !== '0: null') {
            this.owner = this.usersById[e.target.value];
            if (this.selectedParticipantsById.hasOwnProperty(this.owner.id)) {
                delete this.selectedParticipantsById[this.owner.id];
            }
        } else {
            this.owner = null;
        }
        this.participants = [];
        for (const p in this.usersById) {
            if ((this.owner == null || this.usersById[p].id !== this.owner.id) && this.usersById[p].active) {
                this.participants.push(this.usersById[p]);
            }
        }
    }

    /**
     * On select meeting type
     * @param e
     */
    public selectMeetingType(e: any) {
        this.serviceMeeting.meeting_type_id = e.target.value;
    }

    /**
     * On select participant
     * @param e
     */
    public participantsChange(e: any) {
        const participantUserId: number = parseInt(e.target.value);
        if (this.selectedParticipantsById.hasOwnProperty(participantUserId)) {
            delete this.selectedParticipantsById[participantUserId];
        } else {
            let myId: number = null;
            if (this.selectedParticipantsByIdInitial.hasOwnProperty(participantUserId)) {
                myId = this.selectedParticipantsByIdInitial[participantUserId].id;
            }
            this.selectedParticipantsById[participantUserId] = {
                id: myId,
                service_meeting_id: this.serviceMeeting.id,
                participant_user_id: participantUserId
            };
        }
    }

    /**
     * Checks if participant is selected
     * @param id
     */
    public checkParticipants(id: number) {
        return this.selectedParticipantsById.hasOwnProperty(id);

    }

    /**
     * Resets Form Validation
     */
    public resetFormValidation(): void {
        this.serviceMeetingForm.form.markAsUntouched();
    }

    /**
     * Saves service meeting
     * @param value
     * @param valid
     */
    public onFormSubmit({value, valid}: { value: any, valid: boolean }): void {
        this.errorMsg = 'Bitte beheben Sie alle Fehler.';
        const identifier: string = this.isCreationMode ? 'service-meeting-modal' : 'service-meeting-edit-modal';
        if (valid) {
            // Check if start time before end time
            if (parseInt(this.timeStart.replace(/\:/g, '')) - parseInt(this.timeEnd.replace(/\:/g, '')) > 0) {
                this.errorMsg = 'Zeit (Ende) darf nicht vor Zeit (Start) liegen.';
                this.scrollUp(identifier);
            } else {
                this.serviceMeeting.start_date = this.startDate + ' ' + this.timeStart + ':00';
                this.serviceMeeting.end_date = this.startDate + ' ' + this.timeEnd + ':00';
                // Check if date is valid
                if (Utils.isValidDate(this.serviceMeeting.start_date)) {
                    this.serviceMeeting.v_participants = [];
                    for (const spId in this.selectedParticipantsById) {
                        this.serviceMeeting.v_participants.push(this.selectedParticipantsById[spId]);
                    }

                    if (this.serviceMeeting.service_contact_id === -1) {
                        this.serviceMeeting.service_contact_id = null;
                    }

                    if (this.isCreationMode) {
                        this.createMeeting.emit(this.serviceMeeting);
                    } else {
                        this.editMeeting.emit(this.serviceMeeting);
                    }
                    this.errorMsg = '';
                } else {
                    this.errorMsg = 'Bitte korrektes Datum eingeben.';
                    this.scrollUp(identifier);
                }
            }
        } else {
            this.scrollUp(identifier);
        }
    }

}
