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

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

export class InternalMeetingDetailComponent extends FormComponent implements OnInit {

    @Output() editMeeting: EventEmitter<IInternalMeeting> = new EventEmitter<IInternalMeeting>();
    @Output() deleteMeeting: EventEmitter<number> = new EventEmitter<number>();
    @Output() editMeetingReport: EventEmitter<any> = new EventEmitter<any>();
    @ViewChild('internalMeetingDetailEdit', { static: true }) internalMeetingDetailEdit: InternalMeetingEditComponent;
    @ViewChild('internalMeetingReportForm', { static: true }) internalMeetingReportForm: NgForm;

    public internalMeeting: IInternalMeeting;
    public creator: IUser;
    public owner: IUser;
    public participants: IUser[];
    public dateStart: string;
    public dateEnd: string;
    public timeStart: string;
    public timeEnd: string;
    public config: IConfig;
    public isEditMode: boolean;
    public errorMsg: string;
    public reportFormVisible: boolean;
    public reportOld: string;
    public hasAdminRights: boolean;

    constructor(public appService: AppService, 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.internalMeeting = Factory.getEmptyInternalMeeting();
        this.creator = Factory.getEmptyUser();
        this.owner = Factory.getEmptyUser();
        this.participants = [];
        this.dateStart = '';
        this.dateEnd = '';
        this.timeStart = '';
        this.timeEnd = '';
        this.isEditMode = false;
        this.errorMsg = '';
        this.reportFormVisible = false;
        this.reportOld = '';
    }

    /**
     * Set data
     * @param internalMeeting
     */
    public setData(internalMeeting: IInternalMeeting): void {
        this.internalMeeting = internalMeeting;
        this.setMeetingData();
    }

    /**
     * Updates data
     * @param internalMeeting
     */
    public updateData(internalMeeting: IInternalMeeting): void {
        if (!isNull(this.internalMeeting.id)) {
            this.internalMeeting = internalMeeting;
            this.setMeetingData();
        }
    }

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

    /**
     * Edit meeting entry
     */
    public editEntry(): void {
        this.isEditMode = true;
        this.internalMeetingDetailEdit.setData(Utils.deepClone(this.internalMeeting) as IInternalMeeting);
    }

    /**
     * Edits meeting entry
     * @param internalMeeting
     */
    public editInternalMeetingFunction(internalMeeting: IInternalMeeting) {
        this.editMeeting.emit(internalMeeting);
    }

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

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

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

    /**
     * Saves internal 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.internalMeeting.id,
                report: this.internalMeeting.report
            });
            this.errorMsg = '';
        } else {
            this.scrollUp('internal-meeting-edit-report');
        }
    }

}
