import { Component, Input, Output, OnChanges, OnInit, ViewChild, ElementRef, EventEmitter } from '@angular/core';
import { Validators, FormGroup, FormControl } from '@angular/forms';
import { UserInfo } from 'app/models/userInfo.model';
import {
  InnovationIdeaDetailsResponse, InnovationType, Idea, InnovationIdeaPayload, InnovationStatus,
  InnovationIdeaCreatePayload, InnovationIdeaUpdatePayload, InnovationPOCPayload, POCStatus
} from 'app/models/InnovationIdea.model';
import { Location } from '@angular/common';
import { LocalStorageService } from 'angular-2-local-storage';
import { ToastsManager } from 'ng2-toastr/ng2-toastr';
import { Observable } from 'rxjs/Observable';
import { ActivatedRoute, Router } from '@angular/router';
import { PgUserInfoMstr } from 'app/models/user/user.model';
import { InnovationHttpService } from 'app/services/innovation/innovation-http.service';
import { EmployeeHttpService } from 'app/services/employee/employee-http.service';


type submitButtonsType = 'create' | 'submit' | 'close';
@Component({
  selector: 'app-innovation-form',
  templateUrl: './innovation-form.component.html',
  styleUrls: ['./innovation-form.component.scss']
})

export class InnovationFormComponent implements OnChanges, OnInit {
  _idea: Idea;
  @Input()
  get idea() {
    return this._idea;
  }
  set idea(value: Idea) {
    const isInitialValue: boolean = this._idea === undefined;
    this._idea = value;
    if (!isInitialValue) {
      this.ideaChange.emit(this._idea);
    }
  }
  @Output() ideaChange = new EventEmitter<Idea>();

  @Input() formType: InnovationType = InnovationType.idea;

  ideaPayload: InnovationIdeaUpdatePayload;

  innovationFocal$: Observable<{ focalId: number; focalName: string; pgUserInfoMstr: PgUserInfoMstr; createdBy: string; createdDate: number; updatedBy: string; updatedDate: number; }[]>;
  innovationCategories$: Observable<[{ categoryId: number; category: string; createdBy: string; createdDate: any; updatedBy: string; updatedDate: any; }]>;
  coInnovators: { text: string, value: number }[] = [];
  currentUser: UserInfo;

  public view_InnovationFormModel: FormGroup;
  selectedFile: { id: number, name: string} = { id: undefined, name: undefined };
  activeButton = 'create' as submitButtonsType;

  labels = {
    idea: { title: 'idea', inputs: { title: 'Title', desc: 'Synopsis' }},
    poc: { title: 'POC', inputs: { title: 'POC Title', desc: 'POC Synopsis' }},
    ideaPOC: { title: 'POC', inputs: { title: 'POC Title', desc: 'POC Synopsis' }}
  };

  /* Enum var to use in html template */
  enumInnovationType = InnovationType;

  @ViewChild('files') files: ElementRef;
  @ViewChild('submit') submit: ElementRef;
  constructor(
    private employeeHttpService: EmployeeHttpService,
    private innovationHttpService: InnovationHttpService,
    private localStorageService: LocalStorageService,
    private toast: ToastsManager,
    private router: Router,
    private location: Location
  ) {
    const defaultDefinition = { disabled: false, value: '' };
    this.view_InnovationFormModel = new FormGroup({
      title: new FormControl(defaultDefinition, [Validators.required]),
      category: new FormControl(defaultDefinition, [Validators.required]),
      description: new FormControl(defaultDefinition, [Validators.required]),
      coIinnovators: new FormControl([]),
      innovationFocal: new FormControl(defaultDefinition, [Validators.required])

    });
    this.currentUser = this.localStorageService.get('userInfo');
  }

  ngOnInit() {
    this.innovationCategories$ = this.innovationHttpService.getInnovationCategories();
    this.innovationHttpService.coInnovator(this.currentUser.userInfoMstrId)
      .subscribe(r => {
        this.coInnovators = r.map(coinnovator => ({ text: coinnovator.infoDetails.pgUserInfoMstr.fullName, value: coinnovator.infoDetails.pgUserInfoMstr.userInfoMstrId }));
      });
    this.innovationFocal$ = this.innovationHttpService.getAllInnovationFocal();

    if(this.idea) {
      console.log(this.idea,'ideaaa')
      if (this.idea.status == InnovationStatus.Rework) {
        this.activeButton = 'submit';
      }
    }

  }

  ngOnChanges() {
    const defaultDefinition = { disabled: false, value: '' };
    if (this.formType === InnovationType.ideaPOC) {
      let pocTitle, pocDescription: string;
      if (this.idea && this.idea.poc.length > 0) {
        pocTitle = this.idea.poc[0].pocTitle;
        pocDescription = this.idea.poc[0].pocDescription;
        if (this.idea.poc[0].pocFile.id) {
          this.selectedFile = { id: undefined, name: this.idea.poc[0].pocFile.fileName };
        }
        this.activeButton = 'submit';
      }
      this.view_InnovationFormModel = new FormGroup({
        title: new FormControl(pocTitle, [Validators.required]),
        description: new FormControl(pocDescription, [Validators.required])
      });
    } else {
      this.view_InnovationFormModel = new FormGroup({
        title: new FormControl(defaultDefinition, [Validators.required]),
        category: new FormControl(defaultDefinition, [Validators.required]),
        description: new FormControl(defaultDefinition, [Validators.required]),
        coIinnovators: new FormControl([]),
        innovationFocal: new FormControl(defaultDefinition, [Validators.required])

      });
      if (this.idea) {
        this.activeButton = 'submit';
        this.setInnovation();
      }
    }
  }

  /**
   * Update selected file name
   *
   * @memberof InnovationFormComponent
   */
  public fileSelected(): void {
    const input = this.files.nativeElement as HTMLInputElement;
    if (input.files && input.files.length) {
      this.selectedFile.name = 'Uploading file, please wait.';
      this.uploadSelectedFile();
    }
  }


  /**
   * Upload selected file
   *
   * @memberof InnovationFormComponent
   */
  public async uploadSelectedFile(): Promise<boolean> {
    const formData = new FormData(),
    inputFiles = this.files.nativeElement as HTMLInputElement;

    if (!inputFiles.files || !inputFiles.files.length) {
      this.toast.error('Please select a file before upload');
      return Observable.of(false).toPromise();
    }

    formData.append('file', inputFiles.files[0]);

    const response = this.employeeHttpService.uploadEmployeeRelatedFile(formData);
    response.subscribe(result => {
      this.selectedFile.name = inputFiles.files[0].name;
      this.selectedFile.id = result.fileId;
      this.toast.success('File uploaded successfully');
    }, (err) => {
      this.selectedFile.name = undefined;
      this.toast.error('Something went wrong, please try to upload the file again.');
    });
    return response.toPromise().then(() => true).catch(() => false);
  }

  setInnovation() {
    if (this.idea) {
        this.ideaPayload = {
        innovationId: this.idea.innovationId,
        userInfoMstrId: this.idea.creator.id,
        submitterId: this.currentUser.userInfoMstrId,
        title: this.idea.title,
        category: this.idea.category.categoryName,
        description: this.idea.description,
        innovationFocal: this.idea.focal.id,
        status: this.idea.status,
        reviewer: !this.idea.reviewer.id ? this.idea.focal.focalUser.id : this.idea.reviewer.id
      };

      if (this.idea.coInnovators.length > 0) {
        let innovators = [];
        innovators = this.idea.coInnovators.map(innovator => innovator.id);
        this.ideaPayload.innovatorIds = innovators;
        this.view_InnovationFormModel.get('coIinnovators').setValue(innovators);
        this.view_InnovationFormModel.get('innovationFocal').setValue(this.idea.focal.id);

      }
      this.activeButton = this.idea.status === InnovationStatus.Created ? 'submit' : 'close';
      this.view_InnovationFormModel.get('title').setValue(this.idea.title);
      this.view_InnovationFormModel.get('category').setValue(this.idea.category.categoryName);
      this.view_InnovationFormModel.get('description').setValue(this.idea.description);
      this.selectedFile.name = this.idea.file.fileName;
    }
  }

  /**
   * On innovation form submit
   *
   * @memberof InnovationFormComponent
   */
  public async onSubmit(): Promise<void> {
    if (this.view_InnovationFormModel.valid) {
      if (this.formType === InnovationType.ideaPOC) {
        let nextActiveButton = 'submit' as submitButtonsType;
        const updateErrorMsg = 'Something went wrong updating the POC, please try again later';
        const ideaPOC: InnovationPOCPayload = {
          innovationId: this.idea.innovationId,
          pocTitle: this.view_InnovationFormModel.get('title').value,
          pocDescription: this.view_InnovationFormModel.get('description').value
        };
        const innovationUpdatePayload: InnovationIdeaUpdatePayload = {
          submitterId: this.currentUser.userInfoMstrId,
          userInfoMstrId: this.idea.creator.id,
          innovationId: this.idea.innovationId,
          reviewer: this.idea.focal.focalUser.id,
          status: POCStatus.Created,
          pocTitle: ideaPOC.pocTitle,
          pocDescription: ideaPOC.pocDescription
        };
        if (this.selectedFile.id) {
          ideaPOC.pocFileId = this.selectedFile.id;
          ideaPOC.pocFileName = this.selectedFile.name;
          innovationUpdatePayload.pocFileId = this.selectedFile.id;
          innovationUpdatePayload.pocFileName = this.selectedFile.name;
        }
        if (this.activeButton === 'create') {
          this.innovationHttpService.addInnovationPOC(ideaPOC)
          .subscribe((data: InnovationIdeaDetailsResponse) => {
            this.innovationHttpService.updateInnovationIdea(innovationUpdatePayload)
            .subscribe((data2: InnovationIdeaDetailsResponse) => {
              this.activeButton = nextActiveButton;
              this.idea = data2.ideasList[0];
            }, (e) => {
              this.toast.error(updateErrorMsg);
            });
           },
          (e) => {
            nextActiveButton = 'create';
            this.toast.error(updateErrorMsg);
          });
        } else {
          innovationUpdatePayload.status = POCStatus.InProgress;
          this.innovationHttpService.updateInnovationIdea(innovationUpdatePayload)
          .subscribe((data: InnovationIdeaDetailsResponse) => {
            this.activeButton = 'close';
            this.idea = data.ideasList[0];
          }, (e) => {
            console.log(e);
            this.toast.error('Something went wrong updating the innovation, please try again later');
          });
        }
      } else {
        const innovation: InnovationIdeaCreatePayload = {
          submitterId: this.currentUser.userInfoMstrId,
          userInfoMstrId: this.currentUser.userInfoMstrId,
          innovationFocal: +this.view_InnovationFormModel.get('innovationFocal').value,
          title: this.view_InnovationFormModel.get('title').value,
          category: this.view_InnovationFormModel.get('category').value,
          description: this.view_InnovationFormModel.get('description').value,
          fileId: this.selectedFile.id,
          fileName: this.selectedFile.id ? this.selectedFile.name : undefined,
          innovatorIds: this.view_InnovationFormModel.get('coIinnovators').value,
          createdBy: this.currentUser.fullName,
          updatedBy: this.currentUser.fullName
        };
        if (this.idea) {
          let innovationToUpdate:  InnovationIdeaUpdatePayload;
          innovationToUpdate = Object.assign(innovation);
          if (this.formType === InnovationType.idea) {
            innovationToUpdate.status = this.idea.status === InnovationStatus.Created ? InnovationStatus.InProgress : this.idea.status;
          } else {
            innovationToUpdate.status = this.idea.status === POCStatus.Created ? POCStatus.InProgress : this.idea.status;
          }
          innovationToUpdate.reviewer = this.ideaPayload.reviewer;
          innovationToUpdate.userInfoMstrId = this.ideaPayload.userInfoMstrId;
          innovationToUpdate.innovationId = this.idea.innovationId;
          if (this.formType === InnovationType.poc) {
            innovationToUpdate.pocFileId = innovation.fileId;
            innovationToUpdate.pocFileName = innovation.fileName;
            innovationToUpdate.pocDescription = innovation.description;
            innovationToUpdate.pocTitle = innovation.title;
          }
          this.innovationHttpService.updateInnovationIdea(innovationToUpdate).subscribe((d) => {
            this.toast.success('Idea updated successfully');
            this.router.navigate(['/employee/dashboard/innovation']);
          }, (e) => {
            this.toast.error('Something went wrong, please try again later');
          });
        } else {
          this.innovationHttpService.createInnovation(innovation, this.formType).subscribe((d: InnovationIdeaDetailsResponse) => {
            if (this.formType === InnovationType.idea) {
              this.activeButton = 'submit';
              this.idea = d.ideasList[0];
              this.setInnovation();
              this.toast.success('Idea created successfully');
              this.location.go('/employee/first-time-wizard/innovation/idea/' + this.idea.innovationId);
            } else {
              this.toast.success('Idea and POC created successfully');
              this.router.navigate(['/employee/dashboard/innovation']);
            }
          }, (e) => {
            this.toast.error('Something went wrong, please try again later.');
          });
        }
      }
    } else {
      this.toast.error('All fields except attaching a file are required, please fill them.');
    }
  }
}
