import {Component, EventEmitter, Input, OnDestroy, Output} from '@angular/core';
import {FormBuilder, FormGroup, ReactiveFormsModule, Validators} from '@angular/forms';
import {InputTextModule} from 'primeng/inputtext';
import {FileSelectEvent, FileUploadModule} from 'primeng/fileupload';
import {mergeMap, Subscription} from 'rxjs';
import {PostService} from '../../services/post.service';
import {MessageService} from 'primeng/api';
import {EditorModule} from 'primeng/editor';
import {Router} from '@angular/router';
import {Author} from '../../models/author';
import {AuthorService} from '../../services/author.service';
import {AuthService} from '../../auth.service';
import {Button} from 'primeng/button';
import {Textarea} from 'primeng/textarea';
import {FloatLabel} from 'primeng/floatlabel';
import {Post} from '../../models/post';

@Component({
  selector: 'app-post-form',
  standalone: true,
  imports: [
    ReactiveFormsModule,
    InputTextModule,
    FileUploadModule,
    EditorModule,
    Button,
    Textarea,
    FloatLabel
  ],
  templateUrl: './post-form.component.html',
  styleUrls: ['./post-form.component.css']
})
export class PostFormComponent implements OnDestroy {
  @Input() postId: bigint | undefined;
  @Input() isUpdateMode: boolean = false;
  @Input() actualAuthor: Author | undefined;
  @Input() title: string = '';
  @Input() category: string = '';
  @Input() description: string = '';
  @Input() body: string = '';
  @Output() postUpdate: EventEmitter<Post> = new EventEmitter();
  subs: Subscription[] = [];
  form: FormGroup;
  uploadedFile: File | undefined;

  constructor(
    private formBuilder: FormBuilder,
    private postService: PostService,
    private authorService: AuthorService,
    private authService: AuthService,
    private messageService: MessageService,
    private router: Router
  ) {
    this.form = this.formBuilder.group({
      description: ['', [Validators.required, Validators.maxLength(512)]],
      title: ['', [Validators.required, Validators.maxLength(50)]],
      body: ['', [Validators.required]],
      category: ['', [Validators.required, Validators.maxLength(50)]],
    });

    if (this.isUpdateMode && this.postId) {
      this.loadPostData();
    }
  }


  loadPostData(): void {
    if (this.postId) {
      this.subs.push(
        this.postService.getPost(this.postId).subscribe({
          next: (post) => {
            this.form.patchValue({
              title: post.title,
              description: post.description,
              body: post.body,
              category: post.category
            });
          },
          error: (err) => {
            this.failureMessage('Erreur', err.error.message);
          }
        })
      );
    }
  }

  onSelected(event: FileSelectEvent): void {
    if (event.currentFiles && event.currentFiles.length > 0) {
      this.uploadedFile = event.currentFiles[0];
    }
  }

  onSubmit(): void {
    if (this.form.valid && this.uploadedFile) {
      const formData = this.form.value;
      formData.body = this.transformYouTubeLinksToIframes(formData.body);
      const postData: any = {
        title: formData.title,
        description: formData.description,
        body: formData.body,
        category: formData.category
      };

      if (this.isUpdateMode && this.postId) {
        this.subs.push(
          this.postService.updatePost(this.postId, postData, this.authService.getAuthenticatedAuthorToken()!).pipe(
            mergeMap((_) => {
              return this.postService.changeIllustration(this.postId, this.uploadedFile, this.authService.getAuthenticatedAuthorToken()!);
            })
          ).subscribe({
            next: (_) => {
              this.postUpdate.emit(_);
              this.successMessage('Succès', 'Post mis à jour avec succès')
            },
            error: (err) => this.failureMessage('Erreur', err.error.message)
          })
        );
      } else {
        this.subs.push(
          this.postService.createPost(postData, this.authService.getAuthenticatedAuthorToken()!).pipe(
            mergeMap(post =>
              this.authorService.attributePost(this.actualAuthor?.id, post.id, this.authService.getAuthenticatedAuthorToken()!).pipe(
                mergeMap((_) =>
                  this.postService.changeIllustration(post.id, this.uploadedFile, this.authService.getAuthenticatedAuthorToken()!),
                )
              )
            )
          ).subscribe({
            next: () => {
              this.router.navigate(['/']).then(() => {
                this.successMessage('Succès', 'Post créé avec succès')
              });
            },
            error: (err) => this.failureMessage('Erreur', err.error.message)
          })
        );
      }
    }
  }

  private transformYouTubeLinksToIframes(html: string): string {
    // Magie noire
    return html.replace(/<a[^>]*href="(https?:\/\/(?:www\.)?(youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/)([a-zA-Z0-9_-]+)[^"]*)".*?<\/a>/g,
      (_, _url, _prefix, videoId) => {
        return `<iframe width="560" height="315" src="https://www.youtube.com/embed/${videoId}" frameborder="0" allowfullscreen></iframe>`;
      });
  }

  choose(callback: Function) {
    callback();
  }

  successMessage(summary: string, detail: string): void {
    this.messageService.add({
      severity: 'success',
      summary,
      detail,
      life: 3000,
      closable: false
    });
  }

  failureMessage(summary: string, detail: string): void {
    this.messageService.add({
      severity: 'error',
      summary,
      detail,
      life: 3000,
      closable: false
    });
  }

  ngOnDestroy(): void {
    this.subs.forEach((sub) => sub.unsubscribe());
  }
}
