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 {IProduction} from '../../../../model/entities/production';
import {IProductionMeeting} from '../../../../model/entities/production-meeting';
import {IProductionContact} from '../../../../model/entities/production-contact';

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

export class ProductionMeetingEditComponent extends FormComponent implements OnInit {

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

    public production: IProduction;
    public productionMeeting: IProductionMeeting;
    public productionContacts: IProductionContact[];
    public productionContactsById: {};
    public isExistingProductionContact: 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.production = Factory.getEmptyProduction();
        this.productionMeeting = Factory.getEmptyProductionMeeting();
        this.productionContacts = [];
        this.productionContactsById = {};
        this.isExistingProductionContact = 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 production
     * @param productionMeeting
     * @param isCreationMode
     */
    public setData(production: IProduction, productionMeeting: IProductionMeeting, isCreationMode: boolean = false): void {
        this.production = production;
        this.productionMeeting = productionMeeting;
        this.productionContacts = this.production.v_production_contacts;
        this.productionContactsById = Utils.getSortedObjFromArray(this.productionContacts, 'id');
        this.isCreationMode = isCreationMode;
        this.users = this.appService.getConfig().users;
        this.owner = this.productionMeeting.owner_user_id !== null ?
            this.appService.getConfig().vc_user_by_id[this.productionMeeting.owner_user_id] : null;
        this.startDate = Utils.getDateTimeToDisplay(this.productionMeeting.start_date, true, false, false, true);
        this.timeStart = Utils.getDateTimeToDisplay(this.productionMeeting.start_date, false, true);
        this.timeEnd = Utils.getDateTimeToDisplay(this.productionMeeting.end_date, false, true);
        this.meetingTypes = this.appService.getConfig().meeting_types;
        this.selectedParticipantsById = Utils.getSortedObjFromArray(this.productionMeeting.v_participants, 'participant_user_id');
        this.selectedParticipantsByIdInitial = Utils.getSortedObjFromArray(this.productionMeeting.v_participants, 'participant_user_id');
        this.usersById = Utils.getSortedObjFromArray(this.appService.getConfig().users, '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]);
                }
            }
        }
        this.isCreationMode = isCreationMode;

        if (isNull(this.productionMeeting.production_contact_id)) {
            this.productionMeeting.production_contact_id = -1;
        }
        if (this.productionMeeting.production_contact_id > 0) {
            this.isExistingProductionContact = true;
        }
        this.errorMsg = '';
        this.resetFormValidation();
    }

    /**
     * On select contact
     * @param e
     */
    public selectContact(e: any) {
        this.productionMeeting.production_contact_id = e.target.value;
        this.isExistingProductionContact = false;
        this.productionMeeting.gender = null;
        this.productionMeeting.firstname = null;
        this.productionMeeting.lastname = null;
        this.productionMeeting.department = null;
        this.productionMeeting.email = null;
        this.productionMeeting.phone_no = null;
        this.productionMeeting.mobile_no = null;
        if (this.productionMeeting.production_contact_id > 0) {
            this.productionMeeting.gender = this.productionContactsById[this.productionMeeting.production_contact_id].gender;
            this.productionMeeting.firstname = this.productionContactsById[this.productionMeeting.production_contact_id].firstname;
            this.productionMeeting.lastname = this.productionContactsById[this.productionMeeting.production_contact_id].lastname;
            this.productionMeeting.department = this.productionContactsById[this.productionMeeting.production_contact_id].department;
            this.productionMeeting.email = this.productionContactsById[this.productionMeeting.production_contact_id].email;
            this.productionMeeting.phone_no = this.productionContactsById[this.productionMeeting.production_contact_id].phone_no;
            this.productionMeeting.mobile_no = this.productionContactsById[this.productionMeeting.production_contact_id].mobile_no;
            this.isExistingProductionContact = 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.productionMeeting.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,
                production_meeting_id: this.productionMeeting.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.productionMeetingForm.form.markAsUntouched();
    }

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

                    if (this.productionMeeting.production_contact_id === -1) {
                        this.productionMeeting.production_contact_id = null;
                    }

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

}
