import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'
import SASjs, { SASjsConfig } from '@sasjs/adapter'
import { DcAdapterSettings } from 'src/app/models/DcAdapterSettings'
import { DeployService } from 'src/app/services/deploy.service'
import { EventService } from 'src/app/services/event.service'
import { LoggerService } from 'src/app/services/logger.service'
import { SasService } from 'src/app/services/sas.service'

@Component({
  selector: 'app-automatic-deploy',
  templateUrl: './automatic.component.html',
  styleUrls: ['./automatic.component.scss']
})
export class AutomaticComponent implements OnInit {
  @Input() sasJs!: SASjs
  @Input() sasJsConfig: SASjsConfig = new SASjsConfig()
  @Input() dcAdapterSettings: DcAdapterSettings | undefined
  @Input() appLoc: string = ''
  @Input() dcPath: string = ''
  @Input() selectedAdminGroup: string = ''

  @Output() onNavigateToHome: EventEmitter<any> = new EventEmitter<any>()

  public makeDataResponse: string = ''
  public jsonFile: any = null
  public autodeploying: boolean = false
  public autodeployDone: boolean = false
  public recreateDatabaseModal: boolean = false
  public isSubmittingJson: boolean = false
  public isJsonSubmitted: boolean = false
  public recreateDatabase: boolean = false
  public createDatabaseLoading: boolean = false

  /** autoDeployStatus
   * This object presents the status for two steps that we have for deploy.
   * `deployServicePack` - Creating services based on `viya.json`
   * `runMakeData` - Running `makedata` service
   * If any of them is `null` or `false` that means step failed
   * and will be shown to user on deploy done modal.
   */
  public autoDeployStatus: {
    deployServicePack: any
    runMakeData: any
  } = {
    deployServicePack: null,
    runMakeData: null
  }

  constructor(
    private eventService: EventService,
    private deployService: DeployService,
    private sasService: SasService,
    private loggerService: LoggerService
  ) {}

  ngOnInit(): void {}

  /**
   * Executes sas.json file to deploy the backend
   * Method will first try to run the `auto deploy`
   * If that fails the rest of the code is ignored.
   * If request is successfull, method will continue to try
   * to create database if checkbox is toggled on
   */
  public async executeJson() {
    this.autodeploying = true
    this.isSubmittingJson = true

    try {
      let uploadJsonFile = await this.sasJs.deployServicePack(
        this.jsonFile,
        this.dcAdapterSettings?.appLoc,
        undefined,
        undefined,
        true
      )

      this.autoDeployStatus.deployServicePack = true
      this.isJsonSubmitted = true
    } catch (ex: any) {
      let textEx = ''

      if (typeof ex.message !== 'string') {
        textEx = JSON.stringify(ex).replace(/\\/gm, '')
      } else {
        textEx = ex.message
      }

      this.autoDeployStatus.deployServicePack = false
      this.eventService.showInfoModal(
        'Deploy error',
        `Exception: \n ${textEx !== '' ? textEx : ex}`
      )
      this.autodeploying = false
      this.autodeployDone = false

      return
    }

    this.isSubmittingJson = false

    if (this.recreateDatabase) {
      this.createDatabase()
    } else {
      this.autodeployDone = true
    }
  }

  /**
   * Runs the `makedata` request sending the ADMIN and DCPATH values
   */
  public createDatabase() {
    let data = {
      fromjs: [
        {
          ADMIN: this.selectedAdminGroup,
          DCPATH: this.dcPath
        }
      ]
    }

    /**
     * We are overriding default `sasjsConfig` object fields with this object fields.
     * Here we want to run this request using original WEB method.
     * contextName: null is the MUST field for it.
     */
    let overrideConfig = {
      useComputeApi: false,
      contextName: this.sasJsConfig.contextName,
      debug: true
    }

    this.sasJs
      .request(`services/admin/makedata`, data, overrideConfig, () => {
        this.sasService.shouldLogin.next(true)
      })
      .then((res: any) => {
        this.autodeployDone = true

        try {
          this.makeDataResponse = JSON.stringify(res)
        } catch {
          this.makeDataResponse = res
        }

        if (res.result && res.result.length > 0) {
          this.autoDeployStatus.runMakeData = true
        } else {
          this.autoDeployStatus.runMakeData = false
        }
      })
      .catch((err: any) => {
        this.autoDeployStatus.runMakeData = false
        this.autodeployDone = true

        try {
          this.makeDataResponse = JSON.stringify(err)
        } catch {
          this.makeDataResponse = err
        }
      })
  }

  public downloadFile(
    content: any,
    filename: string,
    extension: string = 'txt'
  ) {
    this.deployService.downloadFile(content, filename, extension)
  }

  public async onJsonFileChange(event: any) {
    let file = event.target.files[0]

    this.jsonFile = await this.deployService.readFile(file)
  }

  public recreateDatabaseClicked(event: Event) {
    ;(<HTMLInputElement>event.target).checked === true
      ? (this.recreateDatabaseModal = true)
      : ''
  }

  public clearUploadInput(event: Event) {
    this.deployService.clearUploadInput(event)
  }

  public openSasRequestsModal() {
    this.eventService.openRequestsModal()
  }

  public navigateToHome() {
    this.onNavigateToHome.emit()
  }
}
