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

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

export class InternalMeetingEditComponent extends FormComponent implements OnInit {

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

    public internalMeeting: IInternalMeeting;
    public users: IUser[];
    public usersById: {};
    public possibleOwners: IUser[];
    public possibleOwnersById: {};
    public participants: IUser[];
    public selectedParticipantsById: {};
    public selectedParticipantsByIdInitial: {};
    public owner: IUser;
    public dateStart: string;
    public dateEnd: string;
    public timeStart: string;
    public timeEnd: string;
    public config: IConfig;

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

    ngOnInit() {
        this.config = this.appService.getConfig();
        this.internalMeeting = Factory.getEmptyInternalMeeting();
        this.users = [];
        this.usersById = {};
        this.possibleOwners = [];
        this.possibleOwnersById = {};
        this.participants = [];
        this.selectedParticipantsById = {};
        this.selectedParticipantsByIdInitial = {};
        this.owner = Factory.getEmptyUser();
        this.dateStart = '';
        this.dateEnd = '';
        this.timeStart = '';
        this.timeEnd = '';
    }

    /**
     * Sets data
     * @param internalMeeting
     * @param isCreationMode
     */
    public setData(internalMeeting: IInternalMeeting, isCreationMode = false): void {
        this.internalMeeting = internalMeeting;
        this.users = this.appService.getConfig().users;
        this.isCreationMode = isCreationMode;
        this.owner = this.internalMeeting.owner_user_id !== null ?
            this.appService.getConfig().vc_user_by_id[this.internalMeeting.owner_user_id] : null;
        this.dateStart = Utils.getDateTimeToDisplay(this.internalMeeting.start_date, true, false, false, true);
        this.dateEnd = Utils.getDateTimeToDisplay(this.internalMeeting.end_date, true, false, false, true);
        this.timeStart = Utils.getDateTimeToDisplay(this.internalMeeting.start_date, false, true);
        this.timeEnd = Utils.getDateTimeToDisplay(this.internalMeeting.end_date, false, true);
        this.usersById = Utils.getSortedObjFromArray(this.appService.getConfig().users, 'id');
        this.selectedParticipantsById = Utils.getSortedObjFromArray(this.internalMeeting.v_participants, 'participant_user_id');
        this.selectedParticipantsByIdInitial = Utils.getSortedObjFromArray(this.internalMeeting.v_participants, 'participant_user_id');
        this.participants = [];
        this.possibleOwners = [];
        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]);
                }
            }
        }
        this.errorMsg = '';
        this.resetFormValidation();
    }

    /**
     * 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 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.internalMeeting.id,
                participant_user_id: participantUserId
            };
        }
    }

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

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

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

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

}
