import {
  ChangeDetectionStrategy,
  ChangeDetectorRef,
  Component,
  EventEmitter,
  Input,
  Output,
  inject,
} from '@angular/core'
import { GraphicOverview } from '../../../../../../../../../libs/common/domain/src/lib/model/record'
import { ImageInputComponent } from '../../../../../../../../../libs/ui/elements/src'
import { PlatformServiceInterface } from '../../../../../../../../../libs/common/domain/src/lib/platform.service.interface'
import { NotificationsService } from '../../../../../../../../../libs/feature/notifications/src'
import { TranslateService } from '@ngx-translate/core'
import { Subscription } from 'rxjs'
import { MAX_UPLOAD_SIZE_MB } from '../../../../fields.config'

@Component({
  selector: 'gn-ui-form-field-overviews',
  templateUrl: './form-field-overviews.component.html',
  styleUrls: ['./form-field-overviews.component.css'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true,
  imports: [ImageInputComponent],
})
export class FormFieldOverviewsComponent {
  private platformService = inject(PlatformServiceInterface)
  private notificationsService = inject(NotificationsService)
  private translateService = inject(TranslateService)
  private cd = inject(ChangeDetectorRef)

  @Input() metadataUuid: string
  @Input() value: Array<GraphicOverview>
  @Output() valueChange: EventEmitter<Array<GraphicOverview>> =
    new EventEmitter()

  uploadProgress = undefined
  uploadSubscription: Subscription = null

  protected MAX_UPLOAD_SIZE_MB = MAX_UPLOAD_SIZE_MB

  get firstOverview() {
    return (
      this.value[0] ?? {
        url: null,
        description: '',
      }
    )
  }

  handleFileChange(file: File) {
    this.uploadProgress = 0
    this.uploadSubscription = this.platformService
      .attachFileToRecord(this.metadataUuid, file)
      .subscribe({
        next: (event) => {
          if (event.type === 'progress') {
            this.uploadProgress = event.progress
            this.cd.detectChanges()
          } else if (event.type === 'success') {
            this.uploadProgress = undefined
            this.cd.detectChanges()
            this.emitOverview({
              url: event.attachment.url,
              description: event.attachment.fileName.replace(/\.[^/.]+$/, ''),
            })
          }
        },
        error: (error: Error) => this.handleError(error),
      })
  }

  handleUploadCancel() {
    if (this.uploadSubscription) {
      this.uploadProgress = undefined
      this.uploadSubscription.unsubscribe()
    }
  }

  handleUrlChange(url: string) {
    try {
      const filename = url.split('/').pop()
      this.emitOverview({
        url: new URL(url),
        description: filename,
      })
    } catch (e) {
      this.handleError(e as Error)
    }
  }

  handleAltTextChange(newAltText: string) {
    this.emitOverview({
      url: this.firstOverview.url,
      description: newAltText,
    })
  }

  handleDelete() {
    this.emitOverview(null)
  }

  emitOverview(overView: GraphicOverview | null) {
    this.valueChange.emit(overView ? [overView] : [])
  }

  private handleError = (error: Error) => {
    this.uploadProgress = undefined
    this.cd.markForCheck()
    this.notificationsService.showNotification(
      {
        type: 'error',
        title: this.translateService.instant(
          'editor.record.resourceError.title'
        ),
        text: `${this.translateService.instant(
          'editor.record.resourceError.body'
        )} ${error.message}`,
        closeMessage: this.translateService.instant(
          'editor.record.resourceError.closeMessage'
        ),
      },
      undefined,
      error
    )
  }
}
