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

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

export class CustomerMeetingEditComponent extends FormComponent implements OnInit {

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

    public customer: ICustomer;
    public customerMeeting: ICustomerMeeting;
    public customerContacts: ICustomerContact[];
    public customerContactsById: {};
    public isExistingCustomerContact: 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.customer = Factory.getEmptyCustomer();
        this.customerMeeting = Factory.getEmptyCustomerMeeting();
        this.customerContacts = [];
        this.customerContactsById = {};
        this.isExistingCustomerContact = false;
        this.users = this.appService.getConfig().users;
        this.usersById = this.appService.getConfig().vc_user_by_id;
        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 customer
     * @param customerMeeting
     * @param isCreationMode
     */
    public setData(customer: ICustomer, customerMeeting: ICustomerMeeting, isCreationMode: boolean = false): void {
        this.customer = customer;
        this.customerMeeting = customerMeeting;
        this.customerContacts = this.customer.v_customer_contacts;
        this.customerContactsById = Utils.getSortedObjFromArray(this.customerContacts, 'id');
        this.isCreationMode = isCreationMode;
        this.startDate = Utils.getDateTimeToDisplay(this.customerMeeting.start_date, true, false, false, true);
        this.timeStart = Utils.getDateTimeToDisplay(this.customerMeeting.start_date, false, true);
        this.timeEnd = Utils.getDateTimeToDisplay(this.customerMeeting.end_date, false, true);
        this.meetingTypes = this.appService.getConfig().meeting_types;

        this.owner = this.customerMeeting.owner_user_id !== null ?
                     this.appService.getConfig().vc_user_by_id[this.customerMeeting.owner_user_id] : null;
        this.selectedParticipantsById = Utils.getSortedObjFromArray(this.customerMeeting.v_participants, 'participant_user_id');
        this.selectedParticipantsByIdInitial = Utils.getSortedObjFromArray(this.customerMeeting.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.customerMeeting.customer_contact_id)) {
            this.customerMeeting.customer_contact_id = -1;
        }
        if (this.customerMeeting.customer_contact_id > 0) {
            this.isExistingCustomerContact = true;
        }
        this.errorMsg = '';
        this.resetFormValidation();
    }

    /**
     * On select contact
     * @param e
     */
    public selectContact(e: any) {
        this.customerMeeting.customer_contact_id = e.target.value;
        this.isExistingCustomerContact = false;
        this.customerMeeting.gender = null;
        this.customerMeeting.firstname = null;
        this.customerMeeting.lastname = null;
        this.customerMeeting.department = null;
        this.customerMeeting.email = null;
        this.customerMeeting.phone_no = null;
        this.customerMeeting.mobile_no = null;
        if (this.customerMeeting.customer_contact_id > 0) {
            this.customerMeeting.gender = this.customerContactsById[this.customerMeeting.customer_contact_id].gender;
            this.customerMeeting.firstname = this.customerContactsById[this.customerMeeting.customer_contact_id].firstname;
            this.customerMeeting.lastname = this.customerContactsById[this.customerMeeting.customer_contact_id].lastname;
            this.customerMeeting.department = this.customerContactsById[this.customerMeeting.customer_contact_id].department;
            this.customerMeeting.email = this.customerContactsById[this.customerMeeting.customer_contact_id].email;
            this.customerMeeting.phone_no = this.customerContactsById[this.customerMeeting.customer_contact_id].phone_no;
            this.customerMeeting.mobile_no = this.customerContactsById[this.customerMeeting.customer_contact_id].mobile_no;
            this.isExistingCustomerContact = 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.customerMeeting.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,
                customer_meeting_id: this.customerMeeting.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.customerMeetingForm.form.markAsUntouched();
    }

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

                    if (this.customerMeeting.customer_contact_id == -1) {
                        this.customerMeeting.customer_contact_id = null;
                    }

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

}
