import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, ActivationEnd } from '@angular/router';
import { IndividualService, OrganizationService } from 'src/app/openApis/partyManagement/services';
import { GeographicSiteService } from 'src/app/openApis/geographicSiteManagement/services';
import { MatDialog } from '@angular/material/dialog';
import { ToastrService } from 'ngx-toastr';
import { Individual, Organization, IndividualCreate, IndividualUpdate } from 'src/app/openApis/partyManagement/models';
import { GeographicSite, GeographicSiteCreate, GeographicSiteUpdate } from 'src/app/openApis/geographicSiteManagement/model/models';
import { FormGroup, FormControl, Validators  } from '@angular/forms';
import { Subscription } from 'rxjs';
import { AuthService } from 'src/app/shared/services/auth.service';
import { trigger } from '@angular/animations';
import { fadeIn } from 'src/app/shared/animations/animations';

@Component({
  selector: 'app-edit-individuals',
  templateUrl: './edit-individuals.component.html',
  styleUrls: ['./edit-individuals.component.scss'],
  animations: [ trigger('fadeIn', fadeIn()) ]
})
export class EditIndividualsComponent implements OnInit {

  constructor(
    private activatedRoute: ActivatedRoute,
    private individualService: IndividualService,
    private organizationService: OrganizationService,
    private geographicSiteService: GeographicSiteService,
    private authService: AuthService,
    private router: Router,
    private dialog: MatDialog,
    private toast: ToastrService,
  ) { }

  individualID: string
  individual: Individual
  geographicSite: GeographicSite 

  organizations: Organization[]

  editForm = new FormGroup({
    givenName: new FormControl(),
    familyName: new FormControl(),
    location: new FormControl(),
    contactInfo: new FormGroup({
      city: new FormControl(),
      emailAddress: new FormControl(),
      phoneNumber: new FormControl()
    }),
    geographicSiteInfo: new FormGroup({
      locality: new FormControl(),
      postcode: new FormControl(null, Validators.required),
      stateOrProvince: new FormControl(),
      streetNr: new FormControl(null, Validators.required),
      city: new FormControl(null, Validators.required),
      country: new FormControl(null, Validators.required),
      streetName: new FormControl(null, Validators.required),
      code : new FormControl(),
      description : new FormControl(),
      status : new FormControl(),
      buildingName : new FormControl(),
      levelType : new FormControl(),
      levelNumber : new FormControl(),
      privateStreetName : new FormControl(),
      privateStreetNumber : new FormControl(),
      subAddressName : new FormControl(),
      subAddressType : new FormControl(),
      streetSuffix : new FormControl(),
      streetType : new FormControl()
        })
  })

  predefinedOrganizationCtrl = new FormControl()
  customOrganizationCtrl = new FormControl()

  contactMediums = [
    { mediumType: 'email', contactType: ['email']},
    { mediumType: 'telephone', contactType: ['mobile', 'fixed home', 'fixed office']},
    { mediumType: 'postal', contactType: ['shipping', 'installation']},
  ]

  newIndividual = false

  testbedProvider = false

  subscriptions = new Subscription()

  ngOnInit() {
    // this.retrieveOrganizations()
    this.routerEventsSubscription()

    if (this.activatedRoute.snapshot.params.id)
    {
      this.individualID = this.activatedRoute.snapshot.params.id
      if (this.authService.portalUser && this.authService.portalUser.id === this.individualID) {
        this.individualID = "myuser"
      }
      for(var val of this.authService.portalUserJWT.realm_access.roles){
            if (val ==='TESTBED_PROVIDER') {
              this.testbedProvider=true
              this.retrieveGeographicSite()
              }
          }
      this.retrieveIndividual()
    } else {
      // this.initNewOrganizationFormArray()
      this.newIndividual = true
    }

  }

  routerEventsSubscription() {
    this.subscriptions = this.router.events.subscribe(
      event => {
        if (event instanceof ActivationEnd) {
          this.individualID = this.activatedRoute.snapshot.params.id
          this.retrieveIndividual()
        }
      }
    )
  }

  retrieveOrganizations() {
    this.organizationService.listOrganization({}).subscribe(
      data => { this.organizations = data },
      error => { console.error(error) }
    )
  }

  retrieveIndividual() {
    this.individualService.retrieveIndividual({id: this.individualID}).subscribe(
      data => this.individual = data,
      error => console.error(error),
      () => {
        this.editForm.patchValue({
          givenName: this.individual.givenName,
          familyName: this.individual.familyName,
          location: this.individual.location,
          contactInfo: {
            city: this.individual.contactMedium[0].characteristic.city,
            emailAddress: this.individual.contactMedium[0].characteristic.emailAddress,
            phoneNumber: this.individual.contactMedium[0].characteristic.phoneNumber
          }
        })

        if (this.individual.partyCharacteristic.length) {
          this.customOrganizationCtrl.setValue(this.individual.partyCharacteristic.find( char => char.name === 'organization').value.value)
        }

        if (this.individualID ==="myuser") {
          this.authService.portalUser = this.individual
        }

        //prefefined Organization in Related Party

        //
      }

    )
  }

  updateIndividual() {
    let updateObj: IndividualCreate | IndividualUpdate = {
      familyName: this.editForm.value.familyName,
      givenName: this.editForm.value.givenName,
      location: this.editForm.value.location,
      contactMedium: [{
        mediumType: 'main',
        characteristic: this.editForm.value.contactInfo
      }],
      partyCharacteristic: []
    }

    if (this.customOrganizationCtrl.value)
      updateObj.partyCharacteristic.push({name: 'organization', valueType: 'TEXT', value: {value: this.customOrganizationCtrl.value}})
    // updateObj = this.editForm.value

    let updatedIndividual: Individual
   
    if (this.newIndividual) {
      // const definedCharacteristics = this.editForm.get('partyCharacteristic').value.filter(el => el.value)
      // if (definedCharacteristics.length) updateObj.partyCharacteristic = definedCharacteristics

      this.individualService.createIndividual(updateObj).subscribe(
        data => { updatedIndividual = data },
        error => console.error(error),
        () => {
          if(this.testbedProvider) {
          this.updateGeographicSite(updatedIndividual.id);
          }
          this.newIndividual = false
          this.toast.success("Individual was successfully created")
          this.refreshIndividual(updatedIndividual)
        }
      )
    }
    else {
      this.individualService.patchIndividual({id: this.individual.id, individual: updateObj}).subscribe(
        data => { updatedIndividual = data },
        error => console.error(error),
        () => {
          if(this.testbedProvider) {
            this.updateGeographicSite(updatedIndividual.id);
            }
          this.newIndividual = false
          this.toast.success("Individual was successfully updated")
          this.refreshIndividual(updatedIndividual)
        }
      )
    }
    // this.updateGeographicSite();
  }

  refreshIndividual(updatedIndividual: Individual) {
    // this.individualID = updatedIndividual.id
    this.retrieveIndividual()
    if(this.testbedProvider) {
      this.retrieveGeographicSite()
      }
    console.log("TODO-Retrieve Geographic Site info as well")//TODO
  }

  retrieveGeographicSite(){
    this.geographicSiteService.retrieveGeographicSite(this.individualID).subscribe(
      data => this.geographicSite = data,
      error => console.error(error),
      () => {
        this.editForm.patchValue({
          geographicSiteInfo: {
          code:this.geographicSite.code,
          description: this.geographicSite.description,
          locality: this.geographicSite.place[0].geographicAddress.locality ,
          postcode: this.geographicSite.place[0].geographicAddress.postcode ,
          stateOrProvince: this.geographicSite.place[0].geographicAddress.stateOrProvince ,
          streetNr: this.geographicSite.place[0].geographicAddress.streetNr ,
          streetSuffix: this.geographicSite.place[0].geographicAddress.streetSuffix ,
          streetType: this.geographicSite.place[0].geographicAddress.streetType ,
          streetName: this.geographicSite.place[0].geographicAddress.streetName ,
          city: this.geographicSite.place[0].geographicAddress.city ,
          country: this.geographicSite.place[0].geographicAddress.country ,
          buildingName: this.geographicSite.place[0].geographicAddress.geographicSubAddress.buildingName ,
          levelNumber: this.geographicSite.place[0].geographicAddress.geographicSubAddress.levelNumber ,
          levelType: this.geographicSite.place[0].geographicAddress.geographicSubAddress.levelType ,
          name: this.geographicSite.place[0].geographicAddress.geographicSubAddress.name ,
          privateStreetName: this.geographicSite.place[0].geographicAddress.geographicSubAddress.privateStreetName ,
          privateStreetNumber: this.geographicSite.place[0].geographicAddress.geographicSubAddress.privateStreetNumber ,
          subAddressType: this.geographicSite.place[0].geographicAddress.geographicSubAddress.subAddressType
          }
        
        })

        // if (this.individual.partyCharacteristic.length) {
        //   this.customOrganizationCtrl.setValue(this.individual.partyCharacteristic.find( char => char.name === 'organization').value.value)
        // }

        // if (this.individualID ==="myuser") {
        //   this.authService.portalUser = this.individual
        // }

        //prefefined Organization in Related Party

        //
      }

    )
  }

  updateGeographicSite(id: String){
    if (this.editForm.valid) {
    let updateObj: GeographicSiteCreate | GeographicSiteUpdate ={
        code:this.editForm.value.geographicSiteInfo.code,
        description: this.editForm.value.geographicSiteInfo.description,
        relatedParty: [{
          id:this.individualID
        }],
        externalIdentifier: [],
        calendar:[],
        place:[{'@type':"GeographicAddressValue",
          geographicAddress:{
            '@type':"GeographicAddressValue",
            locality: this.editForm.value.geographicSiteInfo.locality ,
            postcode: this.editForm.value.geographicSiteInfo.postcode ,
            stateOrProvince: this.editForm.value.geographicSiteInfo.stateOrProvince ,
            streetNr: this.editForm.value.geographicSiteInfo.streetNr ,
            streetSuffix: this.editForm.value.geographicSiteInfo.streetSuffix ,
            streetType: this.editForm.value.geographicSiteInfo.streetType ,
            streetName: this.editForm.value.geographicSiteInfo.streetName ,
            city: this.editForm.value.geographicSiteInfo.city ,
            country: this.editForm.value.geographicSiteInfo.country ,
            geographicSubAddress: {
              buildingName: this.editForm.value.geographicSiteInfo.buildingName ,
              levelNumber: this.editForm.value.geographicSiteInfo.levelNumber ,
              levelType: this.editForm.value.geographicSiteInfo.levelType ,
              name: this.editForm.value.geographicSiteInfo.subAddressName ,
              privateStreetName: this.editForm.value.geographicSiteInfo.privateStreetName ,
              privateStreetNumber: this.editForm.value.geographicSiteInfo.privateStreetNumber ,
              subAddressType: this.editForm.value.geographicSiteInfo.subAddressType
            }

          }

        }],
        siteRelationship:[]
    }
    console.log(updateObj)
    let updatedGeographicSite: GeographicSite

    if (this.newIndividual) {

      this.geographicSiteService.createGeographicSite(updateObj).subscribe(
        data => { updatedGeographicSite = data },
        error => console.error(error),
        () => {
          this.toast.success("Geographic site was successfully created")
        }
      )
    }
    else {
      this.geographicSiteService.patchGeographicSite(this.individual.id,updateObj).subscribe(
        data => { updatedGeographicSite = data },
        error => console.error(error),
        () => {
          this.toast.success("Geographic site was successfully updated")
        }
      )
    }

  }
  }

  ngOnDestroy() {
    this.subscriptions.unsubscribe()
  }

}
