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 {IOperatorMeeting} from '../../../../model/entities/operator-meeting';
import {IOperator} from '../../../../model/entities/operator';
import {IOperatorContact} from '../../../../model/entities/operator-contact';

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

export class OperatorMeetingEditComponent extends FormComponent implements OnInit {

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

    public operator: IOperator;
    public operatorMeeting: IOperatorMeeting;
    public operatorContacts: IOperatorContact[];
    public operatorContactsById: {};
    public isExistingOperatorContact: 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.operator = Factory.getEmptyOperator();
        this.operatorMeeting = Factory.getEmptyOperatorMeeting();
        this.operatorContacts = [];
        this.operatorContactsById = {};
        this.isExistingOperatorContact = 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 operator
     * @param operatorMeeting
     * @param isCreationMode
     */
    public setData(operator: IOperator, operatorMeeting: IOperatorMeeting, isCreationMode: boolean = false): void {
        this.operator = operator;
        this.operatorMeeting = operatorMeeting;
        this.operatorContacts = this.operator.v_operator_contacts;
        this.operatorContactsById = Utils.getSortedObjFromArray(this.operatorContacts, 'id');
        this.isCreationMode = isCreationMode;
        this.users = this.appService.getConfig().users;
        this.owner = this.operatorMeeting.owner_user_id !== null ?
            this.appService.getConfig().vc_user_by_id[this.operatorMeeting.owner_user_id] : null;
        this.startDate = Utils.getDateTimeToDisplay(this.operatorMeeting.start_date, true, false, false, true);
        this.timeStart = Utils.getDateTimeToDisplay(this.operatorMeeting.start_date, false, true);
        this.timeEnd = Utils.getDateTimeToDisplay(this.operatorMeeting.end_date, false, true);
        this.meetingTypes = this.appService.getConfig().meeting_types;
        this.selectedParticipantsById = Utils.getSortedObjFromArray(this.operatorMeeting.v_participants, 'participant_user_id');
        this.selectedParticipantsByIdInitial = Utils.getSortedObjFromArray(this.operatorMeeting.v_participants, 'participant_user_id');
        this.participants = [];
        this.usersById = Utils.getSortedObjFromArray(this.appService.getConfig().users, 'id');
        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.operatorMeeting.operator_contact_id)) {
            this.operatorMeeting.operator_contact_id = -1;
        }
        if (this.operatorMeeting.operator_contact_id > 0) {
            this.isExistingOperatorContact = true;
        }
        this.errorMsg = '';
        this.resetFormValidation();
    }

    /**
     * On select contact
     * @param e
     */
    public selectContact(e: any) {
        this.operatorMeeting.operator_contact_id = e.target.value;
        this.isExistingOperatorContact = false;
        this.operatorMeeting.gender = null;
        this.operatorMeeting.firstname = null;
        this.operatorMeeting.lastname = null;
        this.operatorMeeting.department = null;
        this.operatorMeeting.email = null;
        this.operatorMeeting.phone_no = null;
        this.operatorMeeting.mobile_no = null;
        if (this.operatorMeeting.operator_contact_id > 0) {
            this.operatorMeeting.gender = this.operatorContactsById[this.operatorMeeting.operator_contact_id].gender;
            this.operatorMeeting.firstname = this.operatorContactsById[this.operatorMeeting.operator_contact_id].firstname;
            this.operatorMeeting.lastname = this.operatorContactsById[this.operatorMeeting.operator_contact_id].lastname;
            this.operatorMeeting.department = this.operatorContactsById[this.operatorMeeting.operator_contact_id].department;
            this.operatorMeeting.email = this.operatorContactsById[this.operatorMeeting.operator_contact_id].email;
            this.operatorMeeting.phone_no = this.operatorContactsById[this.operatorMeeting.operator_contact_id].phone_no;
            this.operatorMeeting.mobile_no = this.operatorContactsById[this.operatorMeeting.operator_contact_id].mobile_no;
            this.isExistingOperatorContact = 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.operatorMeeting.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,
                operator_meeting_id: this.operatorMeeting.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.operatorMeetingForm.form.markAsUntouched();
    }

    /**
     * Saves operator 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 ? 'operator-meeting-modal' : 'operator-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.operatorMeeting.start_date = this.startDate + ' ' + this.timeStart + ':00';
                this.operatorMeeting.end_date = this.startDate + ' ' + this.timeEnd + ':00';
                // Check if date is valid
                if (Utils.isValidDate(this.operatorMeeting.start_date)) {
                    this.operatorMeeting.v_participants = [];
                    for (const spId in this.selectedParticipantsById) {
                        this.operatorMeeting.v_participants.push(this.selectedParticipantsById[spId]);
                    }

                    if (this.operatorMeeting.operator_contact_id == -1) {
                        this.operatorMeeting.operator_contact_id = null;
                    }

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

}
