import {
    ChangeDetectionStrategy,
    ChangeDetectorRef,
    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 {MeetingService} from '../../../../services/meeting.service';
import {ScrollToService} from '@nicky-lenaers/ngx-scroll-to';
import {Const} from '../../../../utils/const';
import {Factory} from '../../../../factory/factory';
import {isNull} from 'util';
import {Utils} from '../../../../utils/utils';
import {IOperatorMeeting} from '../../../../model/entities/operator-meeting';
import {OperatorMeetingEditComponent} from '../operator-meeting-edit/operator-meeting-edit.component';
import {IOperator} from '../../../../model/entities/operator';
import {OperatorService} from '../../../../services/operator.service';

@Component({
  selector: 'app-operator-meeting-detail',
  templateUrl: './operator-meeting-detail.component.html',
  styleUrls: ['./operator-meeting-detail.component.scss'],
    // NOTE: We need manual change detection in this component
    changeDetection: ChangeDetectionStrategy.OnPush,
})

export class OperatorMeetingDetailComponent extends FormComponent implements OnInit {

    @Output() editMeeting: EventEmitter<IOperatorMeeting> = new EventEmitter<IOperatorMeeting>();
    @Output() deleteMeeting: EventEmitter<number> = new EventEmitter<number>();
    @Output() editMeetingReport: EventEmitter<any> = new EventEmitter<any>();
    @ViewChild('operatorMeetingDetailEdit', { static: true }) operatorMeetingDetailEdit: OperatorMeetingEditComponent;
    @ViewChild('operatorMeetingReportForm', { static: true }) operatorMeetingReportForm: NgForm;

    public operator: IOperator;
    public operatorMeeting: IOperatorMeeting;
    public isEditMode: boolean;
    public creator: IUser;
    public owner: IUser;
    public participants: IUser[];
    public meetingType: IMeetingType;
    public date: string;
    public timeStart: string;
    public timeEnd: string;
    public config: IConfig;
    public reportFormVisible: boolean;
    public reportOld: string;
    public hasAdminRights: boolean;

    constructor(
        public appService: AppService,
        private operatorService: OperatorService,
        private meetingService: MeetingService,
        protected scrollToService: ScrollToService,
        private ref: ChangeDetectorRef
    ) {
        super(scrollToService);
    }

    ngOnInit() {
        this.hasAdminRights = this.appService.userHasRole(Const.USER_ROLE_ADMIN);
        this.config = this.appService.getConfig();
        this.operator = Factory.getEmptyOperator();
        this.operatorMeeting = Factory.getEmptyOperatorMeeting();
        this.creator = Factory.getEmptyUser();
        this.owner = Factory.getEmptyUser();
        this.participants = [];
        this.meetingType = Factory.getEmptyMeetingType();
        this.date = '';
        this.timeStart = '';
        this.timeEnd = '';
        this.reportFormVisible = false;
        this.reportOld = '';
    }

    /**
     * Set data
     * @param operator
     * @param operatorMeeting
     */
    public setData(operator: IOperator, operatorMeeting: IOperatorMeeting): void {
        this.operator = operator;
        this.operatorMeeting = operatorMeeting;
        this.setMeetingData();
    }

    /**
     * Updates data
     * @param operator
     */
    public updateData(operator: IOperator): void {
        this.operator = operator;
        if (!isNull(this.operatorMeeting.id)) {
            for (let i = 0; i < this.operator.v_operator_meetings.length; i++) {
                if (this.operator.v_operator_meetings[i].id == this.operatorMeeting.id) {
                    this.operatorMeeting = this.operator.v_operator_meetings[i];
                }
            }
            this.setMeetingData();
        }
    }

    /**
     * Sets variables for meeting
     */
    public setMeetingData() {
        this.errorMsg = '';
        this.reportFormVisible = false;
        this.reportOld = this.operatorMeeting.report;
        this.creator = this.appService.getConfig().vc_user_by_id[this.operatorMeeting.creation_user_id];
        this.owner = this.appService.getConfig().vc_user_by_id[this.operatorMeeting.owner_user_id];
        this.participants = [];
        for (let i = 0; i < this.operatorMeeting.v_participants.length; i++) {
            this.participants.push(this.appService.getConfig().vc_user_by_id[this.operatorMeeting.v_participants[i].participant_user_id]);
        }
        this.meetingType = this.appService.getConfig().vc_meeting_types_by_id[this.operatorMeeting.meeting_type_id];
        this.date = Utils.getDateTimeToDisplay(this.operatorMeeting.start_date);
        this.timeStart = Utils.getDateTimeToDisplay(this.operatorMeeting.start_date, false, true);
        this.timeEnd = Utils.getDateTimeToDisplay(this.operatorMeeting.end_date, false, true);
        this.isEditMode = false;
        this.resetFormValidation();
        // NOTE: We need manual change detection in this component
        this.ref.detectChanges();
    }

    /**
     * Edit meeting entry
     */
    public editEntry(): void {
        this.isEditMode = true;
        this.operatorMeetingDetailEdit.setData(this.operator, Utils.deepClone(this.operatorMeeting) as IOperatorMeeting);
    }

    /**
     * Edits meeting entry
     * @param operatorMeeting
     */
    public editOperatorMeetingFunction(operatorMeeting: IOperatorMeeting) {
        this.editMeeting.emit(operatorMeeting);
    }

    /**
     * Delete meeting entry
     */
    public deleteEntry(): void {
        const confirmAction = confirm('Wollen Sie diesen Eintrag wirklich löschen?');
        if (confirmAction == true) {
            this.deleteMeeting.emit(this.operatorMeeting.id);
        }
    }

    /**
     * Check if edit report after meeting has started
     */
    public editReport(): void {
        this.meetingService.apiCheckOperatorMeetingReport(this.operatorMeeting.id).subscribe(
            data => {
                this.reportFormVisible = data.result_data as boolean;
                // NOTE: We need manual change detection in this component
                this.ref.detectChanges();
                this.scrollUp('operator-meeting-edit-report');
            },
            error => {
            }
        );
    }

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

    /**
     * Saves operator meeting report
     * @param value
     * @param valid
     */
    public onFormSubmit({value, valid}: { value: any, valid: boolean }): void {
        this.errorMsg = 'Bitte beheben Sie alle Fehler.';
        if (valid) {
            this.editMeetingReport.emit({
                id: this.operatorMeeting.id,
                report: this.operatorMeeting.report
            });
            this.errorMsg = '';
        } else {
            this.scrollUp('operator-meeting-edit-report');
        }
    }

}
