 import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
import { CommonModule } from "@angular/common";
import {
  CdkDragDrop,
  DragDropModule,
  moveItemInArray,
} from "@angular/cdk/drag-drop";
import { ImagesIncludeId } from "../../interfaces/image.interface";

export interface ImageObject {
  oldImage: boolean;
  image: string;
  id?: string;
  file?: File;
}

export interface ImagesIncludeIdExtended extends ImagesIncludeId {
  file?: File;
}

export interface ImageApiResponse {
  data: {
    downloadUrl: string;
  };
}

@Component({
  selector: "app-image-uploader",
  standalone: true,
  imports: [CommonModule, DragDropModule],
  templateUrl: "./image-uploader.component.html",
  styleUrls: ["./image-uploader.component.scss"],
})
export class ImageUploaderComponent {
  @Input() set previewImages(images: ImagesIncludeId[]) {
    this._previewImages = [...images];
    this.previewImagesChange.emit(this._previewImages);
  }


  get previewImages(): ImagesIncludeId[] {
    return this._previewImages;
  }

  private _previewImages: ImagesIncludeIdExtended[] = [];

  @Output() previewImagesChange = new EventEmitter<ImagesIncludeId[]>();

  @Output() imagesChange = new EventEmitter<File[]>();
  @Output() error = new EventEmitter<string>();

  selectedFiles: File[] = [];
  enlargedImage: string | null = null;

  @Input() maxImages: number = 5;
  @Input() maxSizeMb: number = 2;
  @Input() allowedTypes: string[] = ["image/jpeg", "image/png", "image/webp"];

  onFileSelected(event: Event) {
    const input = event.target as HTMLInputElement;
    if (!input.files) return;

    const files = Array.from(input.files);

    if (this.previewImages.length + files.length > this.maxImages) {
      this.error.emit(`Você pode enviar no máximo ${this.maxImages} imagens.`);
      return;
    }

    for (const file of files) {
      if (!this.allowedTypes.includes(file.type)) {
        this.error.emit(`Formato inválido: ${file.type}`);
        continue;
      }

      const sizeMb = file.size / (1024 * 1024);
      if (sizeMb > this.maxSizeMb) {
        this.error.emit(`A imagem "${file.name}" excede ${this.maxSizeMb}MB.`);
        continue;
      }

      const reader = new FileReader();
      reader.onload = (e: ProgressEvent<FileReader>) => {
        const result = e.target?.result as string;
        this._previewImages.push({
          id: null,
          image: result,
          file: file,
        });
        this.previewImagesChange.emit(this._previewImages);
      };
      reader.readAsDataURL(file);

      this.selectedFiles.push(file);
    }

    this.imagesChange.emit(this.selectedFiles);
  }

  openImage(image: string | File) {
    if (typeof image === 'string') {
      this.enlargedImage = image;
    } 
    else {
      this.createObjectUrlFromFile(image);
    }
  }
  
  private createObjectUrlFromFile(file: File) {
    const objectUrl = URL.createObjectURL(file);
    this.enlargedImage = objectUrl;
  }

  closeImage() {
    this.enlargedImage = null;
  }

  onDrop(event: CdkDragDrop<ImageObject[]>) {
    moveItemInArray(
      this.previewImages,
      event.previousIndex,
      event.currentIndex
    );
    this.previewImagesChange.emit(this._previewImages);

    if (this.selectedFiles.length === this._previewImages.length) {
      moveItemInArray(
        this.selectedFiles,
        event.previousIndex,
        event.currentIndex
      );
      this.imagesChange.emit(this.selectedFiles);
    }
  }

  removeImage(index: number) {
    this.previewImages.splice(index, 1);
    this.previewImagesChange.emit(this.previewImages);

    this.selectedFiles.splice(index, 1);
    this.imagesChange.emit(this.selectedFiles);
  }

  clearAll() {
    this.previewImages = [];
    this.previewImagesChange.emit(this._previewImages);

    this.selectedFiles = [];
    this.imagesChange.emit([]);
  }
}
