import {Component, Input, OnInit, Output, EventEmitter, ViewChild} from '@angular/core';
import {FormControl, FormGroup, Validators} from '@angular/forms';
import {AuthService} from '../../service/auth.service';
import {LoanModel} from '../../models/loan.model';
import {RewardModel} from '../../models/reward.model';
import {PeopleModel, RelevantPeopleModel} from '../../models/people.model';
import {debounce} from 'ts-debounce';
import {LoanSingleService} from '../../service/loan.single.service';
import {ClonerService} from '../../service/clone.service';
import {PeopleService} from '../../service/people.service';
import {Observable, of} from 'rxjs';
import {map} from 'rxjs/operators';



const createFormGroup = dataItem => new FormGroup({
  Id: new FormControl(dataItem.Id),
  To: new FormControl(dataItem.To, [Validators.required, Validators.maxLength(128), Validators.minLength(1)]),
  From: new FormControl(dataItem.From),
  Role: new FormControl({value: dataItem.Role, disabled: true} , [Validators.required, Validators.minLength(2), Validators.maxLength(40)]),
  Amount: new FormControl(dataItem.Amount, Validators.compose([Validators.required, Validators.min(0), Validators.max(1000000)])),
  Description: new FormControl(dataItem.Description, [Validators.required, Validators.maxLength(128)]),
  Ts: new FormControl( dataItem.Ts, Validators.required)
});

@Component({
  selector: 'app-loan-people-reward',
  templateUrl: './people-reward.component.html',
  styleUrls: ['./people-reward.component.scss']
})
export class PeopleRewardComponent implements OnInit {

  @Input() public Loan: LoanModel;
  @Output() public NotifyNext = new EventEmitter<boolean>();
  @Output() public NotifyPrev = new EventEmitter<boolean>();
  @Output() public errorOccurred = new EventEmitter<string>();

  public relevantPeople: RelevantPeopleModel[] = [];
  public total = 0;

  public pendingReward: RewardModel[] = [];
  public paidReward: RewardModel[] = [];

  public formGroup: FormGroup;
  private editedRowIndex: number;

  public existingRoles: string[] = [
    'Broker',
    'Client',
    'Referral',
    'Admin'
  ];

  public existingPayDescription: string[] = [
    'Upfront',
    'Broker Fee',
    'SFM Incentive',
    'Special Reward',
    'Discount',
    'Fringe Cost',
    'Unknown',
    'Trail'
  ];

  private debounceFilter: any ;

  constructor(private ls: LoanSingleService,
              private auth: AuthService,
              private dcs: ClonerService
              ) {
  }

  public ngOnInit(): void {
    this.initPeople(); // make sure people has the one that we need
    this.initReward();
  }

  public initPeople(): void{
    this.relevantPeople = this.Loan.getRelevantPeople();
  }

  public initReward(): void {
    this.Loan.Reward.forEach((r) => {
      const o = this.dcs.deepClone<RewardModel>(r);
      if ( r.PayOutId > 0 ){
        this.paidReward.push(o);
      }else{
        this.pendingReward.push(o);
        this.pendingReward.sort((a, b) => a.Ts > b.Ts ?  -1 : 1 );
      }
    });
  }

  public addHandler({ sender }): void {
    this.closeEditor(sender);
    this.formGroup = createFormGroup({
      Id: 0,
      To: '',
      From: '',
      Role: 'Unknown',
      Amount: 0,
      Description: '',
      PayOutId: 0,
      Ts: new Date()
    });

    sender.addRow(this.formGroup);
  }

  public editHandler({ sender, rowIndex, dataItem }): void {
    this.closeEditor(sender);
    // console.log(sender);

    this.formGroup = createFormGroup(dataItem);
    this.editedRowIndex = rowIndex;
    sender.editRow(rowIndex, this.formGroup);
    // console.log('editing' , dataItem, this.formGroup);
  }

  public cancelHandler({ sender, rowIndex }): void{
    // console.log(sender);
    this.closeEditor(sender, rowIndex);
  }

  public saveHandler({ sender, rowIndex, formGroup, isNew }): void {
    const reward = formGroup.value;
    reward.From = '0'; // Admin

    // reward.Ts = new Date(); // Now
    reward.LoanId = this.Loan.Id; // Enforce LoanId
    reward.PayOutId = 0; // make sure it is not paid
    this.ls.saveReward(reward, isNew).subscribe(
      resp => {
        if ( reward.Id === 0 ) {
          const r = this.Loan.addReward(resp.Amount, resp.Description, resp.Id, resp.LoanId, resp.PayOutId, resp.To, resp.From, resp.Ts);
          this.pendingReward.unshift(r);
        }else{
          const  idx = this.pendingReward.findIndex( v => v.Id === reward.Id);
          // update
          this.pendingReward[idx].To = reward.To;
          this.pendingReward[idx].Amount = reward.Amount;
          this.pendingReward[idx].Description = reward.Description;
          this.pendingReward[idx].Ts = reward.Ts;
          // update Loan
          this.Loan.updateReward(resp.Amount, resp.Description, resp.Id, resp.LoanId, resp.PayOutId, resp.To, resp.From, resp.Ts);
        }
        // console.log(resp);
      }

    );
    sender.closeRow(rowIndex);
  }

  peopleChanged(id: string): void {
    this.formGroup.get('Role').setValue(this.Loan.getRoleById(id));
  }

  public removeHandler({ dataItem }): void {

    const na = this.pendingReward.filter(v => {
      return v.Id !== dataItem.Id;
    });
    this.Loan.removeReward(dataItem.Id);
    this.pendingReward = na;
    this.ls.removeReward(dataItem);
  }

  private closeEditor(grid, rowIndex = this.editedRowIndex): void {
    grid.closeRow(rowIndex);
    this.editedRowIndex = undefined;
    this.formGroup = undefined;
  }

  public getContactImageUrl(contactId: string): string {
    return this.auth.getUrl('avatar/' + contactId);
  }

  public photoURL(peopleId: string): string {
    const url = this.auth.getUrl('avatar/') + peopleId;
    return 'url("' + url + '")';
  }

  public UserName(dataItem: RewardModel): string {
    return dataItem.UserName;
  }

  public next(): void{
     this.NotifyNext.emit(true);
  }

  public prev(): void {
    this.NotifyPrev.emit(true);
  }

}
