import { Component, ElementRef, NgZone, OnInit, ViewChild } from '@angular/core';
import { FormBuilder, FormGroup, Validators, ReactiveFormsModule } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { CommonModule } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { EditorModule } from '@tinymce/tinymce-angular';
import { HeaderComponent } from '../header/header.component';
import { AuthService } from '../auth.service';
import { AllapiService } from '../allapi.service';
import { TransliterateService } from '../transliterate.service';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';
import { Subject } from 'rxjs';

declare var tinymce: any;

@Component({
  selector: 'app-create',
  standalone: true,
  imports: [CommonModule, HeaderComponent, ReactiveFormsModule, EditorModule],
  templateUrl: './create.component.html',
  styleUrl: './create.component.css'
})
export class CreateComponent implements OnInit {
  storyForm!: FormGroup;
  storyId: number = 0;
  selectedAudioFile: File | null = null;
  successMessage: string = '';
  errorMessage: string = '';
  message: string = '';
  currentLang: string = 'en';
  isLoading: boolean = true;
  editorInstance: any;
  private transliterationSubject = new Subject<{text: string, lang: string}>();

  videoFile: File | null = null;
videoUploadProgress: number | null = null;
uploadedVideoUrl: string = '';
videoUploading: boolean = false;

  @ViewChild('audioInput') audioInput!: ElementRef<HTMLInputElement>;

  constructor(
    private fb: FormBuilder,
    private route: ActivatedRoute,
    public router: Router,
    private http: HttpClient,
    private authService: AuthService,
    private contentService: AllapiService,
    private transliterateService: TransliterateService,
    private zone: NgZone
  ) {}

  ngOnInit(): void {
    const paramId = this.route.snapshot.paramMap.get('storyId');
    this.storyId = paramId ? Number(paramId) : 0;

    this.storyForm = this.fb.group({
      story_title: ['', Validators.required],
      story_content: ['', Validators.required],
      video_link: [''],
      audio_link: ['']
    });

    this.transliterationSubject.pipe(
      debounceTime(300),
      distinctUntilChanged((prev: {text: string, lang: string}, curr: {text: string, lang: string}) => 
        prev.text === curr.text && prev.lang === curr.lang
      ),
      switchMap(({text, lang}) => 
        this.transliterateService.transliterateWord(text, lang)
      )
    ).subscribe(transliterated => {
      this.applyTransliteration(transliterated);
    });
  }

onEditorInit(event: any): void {
  this.editorInstance = event.editor;

  this.editorInstance.on('keydown', (e: any) => {
    if ((e.key === ' ' || e.key === 'Enter') && this.currentLang !== 'en') {
      const rng = this.editorInstance.selection.getRng();
      const node = rng.startContainer;

      if (node.nodeType === Node.TEXT_NODE) {
        const fullText = (node as Text).data;
        const offset = rng.startOffset;
        const beforeCursor = fullText.slice(0, offset);
        const afterCursor = fullText.slice(offset);
        const words = beforeCursor.split(/\s+/);
        const lastWord = words[words.length - 1];

        if (lastWord && /^[a-zA-Z]+$/.test(lastWord)) {
          e.preventDefault(); // Prevent default space/enter

          this.transliterateService.transliterateWord(lastWord, this.currentLang).subscribe((convertedWord) => {
            this.zone.run(() => {
              // Replace last word with transliterated + space
              words[words.length - 1] = convertedWord;
              const updatedBefore = words.join(' ') + ' ';
              const updatedText = updatedBefore + afterCursor;
              (node as Text).data = updatedText;

              // Set cursor to after the transliterated word
              const newOffset = updatedBefore.length;
              const newRange = document.createRange();
              newRange.setStart(node, newOffset);
              newRange.setEnd(node, newOffset);
              this.editorInstance.selection.setRng(newRange);
            });
          });
        }
      }
    }
  });
}

  private isLatin(text: string): boolean {
    return /^[a-zA-Z]+$/.test(text);
  }

  private applyTransliteration(transliterated: string): void {
    this.zone.run(() => {
      const content = this.editorInstance.getContent({ format: 'text' });
      const words = content.trim().split(/\s+/);
      words[words.length - 1] = transliterated;
      
      const newContent = words.join(' ') + ' ';
      this.editorInstance.setContent(newContent);
      
      // Move cursor to end
      const body = this.editorInstance.getBody();
      const range = this.editorInstance.dom.createRng();
      range.setStart(body, 1);
      range.setEnd(body, 1);
      this.editorInstance.selection.setRng(range);
    });
  }

  onLanguageChange(event: Event): void {
    const target = event.target as HTMLSelectElement;
    this.currentLang = target.value;
  }

  onAudioFileSelected(event: Event): void {
    const target = event.target as HTMLInputElement;
    const file = target.files?.[0];
    if (file) {
      this.selectedAudioFile = file;
    }
  }

  onVideoSelected(event: Event) {
  const input = event.target as HTMLInputElement;
  const file = input.files?.[0] ?? null;
  if (!file) return;

  // optional: validate size/type
  const maxMB = 200; // adjust as you wish
  if (file.size > maxMB * 1024 * 1024) {
    alert('Video too large. Max ' + maxMB + 'MB.');
    return;
  }

  this.videoFile = file;
  this.videoUploadProgress = 0;
  this.videoUploading = true; // 🔹 start loading

  this.uploadVideoFile();
}
uploadVideoFile() {
  if (!this.videoFile) return;

  const fd = new FormData();
  fd.append('video', this.videoFile, this.videoFile.name);

  this.http.post('https://infoways.in/funtelapi/upload_video.php', fd, {
    reportProgress: true,
    observe: 'events'
  }).subscribe({
    next: (event: any) => {
      // Upload progress
      if (event.type === 1 && event.total) { 
        this.videoUploadProgress = Math.round(100 * event.loaded / event.total);
      } 
      // Upload complete
      else if (event.type === 4) { 
        this.videoUploading = false; // 🔹 stop loading
        if (event.body && event.body.status === 'success') {
          this.uploadedVideoUrl = event.body.url;
          this.videoUploadProgress = 100;
          this.storyForm.patchValue({ video_link: event.body.url });
        } else {
          alert('Upload failed: ' + (event.body?.message || 'Unknown'));
          this.videoUploadProgress = null;
        }
      }
    },
    error: err => {
      this.videoUploading = false; // 🔹 stop loading on error
      console.error('Upload error', err);
      alert('Upload failed.');
      this.videoUploadProgress = null;
    }
  });
}


  triggerFileInput(): void {
    this.audioInput.nativeElement.click();
  }

  onDragOver(event: DragEvent): void {
    event.preventDefault();
    event.stopPropagation();
  }

  onDrop(event: DragEvent): void {
    event.preventDefault();
    event.stopPropagation();

    const file = event.dataTransfer?.files[0];
    if (file && (file.type === 'audio/mp3' || file.type === 'audio/wav')) {
      this.selectedAudioFile = file;
    } else {
      alert("Only MP3 or WAV files are allowed.");
    }
  }

  onSubmit(isPublish: boolean = false): void {
    const userId = this.authService.getCurrentUserId();
    if (!userId) {
      alert('You must be logged in to save a story.');
      this.router.navigate(['login']);
      return;
    }

    if (this.storyForm.invalid) {
      alert('Please complete all required fields');
      return;
    }

    const formValues = this.storyForm.value;
    const formData = new FormData();
    formData.append('user_id', userId.toString());
    formData.append('story_title', formValues.story_title);
    formData.append('story_content', formValues.story_content);
    formData.append('story_id', this.storyId.toString());
    formData.append('video_link', formValues.video_link || '');
    formData.append('status', isPublish ? '1' : '0');
    formData.append('audio_link', formValues.audio_link || '');

    this.http.post('https://infoways.in/funtelapi/addstory.php', formData).subscribe({
      next: (res: any) => {
        if (res.status === 'success') {
          this.successMessage = isPublish ? '✓ Story Published!' : '✓ Draft Saved!';
          this.errorMessage = '';
          setTimeout(() => {
            this.successMessage = '';
            window.scrollTo({ top: 0, behavior: 'smooth' });
            this.router.navigate(['/episode', `${this.storyId}-` + this.slugify(formValues.story_title)]);
          }, 2000);
        } else {
          this.errorMessage = '⚠ Error: ' + res.message;
          this.successMessage = '';
        }
      },
      error: (err) => {
        console.error('⚠ API error', err);
        alert('Something went wrong.');
      }
    });
  }

publishStory(): void {
  const userId = this.authService.getCurrentUserId();
  if (!userId) {
    this.errorMessage = '⚠ You must be logged in to publish a story';
    this.router.navigate(['/login']);
    return;
  }

  if (this.storyForm.invalid) {
    this.markFormGroupTouched(this.storyForm);
    this.errorMessage = '⚠ Please complete all required fields';
    return;
  }

  const formValues = this.storyForm.value;
  const formData = new FormData();

  formData.append('user_id', userId.toString());
  formData.append('story_title', formValues.story_title.trim());
  formData.append('story_content', formValues.story_content.trim());
  formData.append('story_id', this.storyId.toString()); // This should be 107 in your case
  formData.append('status', '1'); // Mark content as published

  if (formValues.video_link?.trim()) {
    formData.append('video_link', formValues.video_link.trim());
  }

  if (formValues.audio_link?.trim()) {
    formData.append('audio_link', formValues.audio_link.trim());
  }

  this.isLoading = true;
  this.errorMessage = '';
  this.successMessage = '';

  // First API: Save content
  this.http.post('https://infoways.in/funtelapi/addstory.php', formData).subscribe({
    next: (res: any) => {
      if (res.status !== 'success') {
        this.handleError('⚠ Error saving content: ' + res.message);
        return;
      }

      // Second API: Publish story
      const publishData = new FormData();
      publishData.append('story_id', this.storyId.toString()); // Use the existing storyId (107)
      publishData.append('story_title', formValues.story_title.trim());
      publishData.append('story_content', formValues.story_content.trim());

      if (formValues.audio_link?.trim()) {
        publishData.append('audio_link', formValues.audio_link.trim());
      }
      if (formValues.video_link?.trim()) {
        publishData.append('video_link', formValues.video_link.trim());
      }

      this.http.post('https://infoways.in/funtelapi/publish_story.php', publishData).subscribe({
        next: (publishRes: any) => {
          this.isLoading = false;

          if (publishRes.status !== 'success') {
            this.handleError('⚠ Error publishing story: ' + publishRes.message);
            return;
          }

          this.successMessage = '✓ Story Published Successfully!';
          setTimeout(() => {
            // Redirect to episode page with the same storyId and slugged title
            this.router.navigate(['/episode', `${this.storyId}-${this.slugify(formValues.story_title)}`]);
            window.scrollTo({ top: 0, behavior: 'smooth' });
          }, 2000);
        },
        error: (publishErr) => {
          this.handleError('⚠ Error publishing story', publishErr);
        }
      });
    },
    error: (err) => {
      this.handleError('⚠ Error saving content', err);
    }
  });
}

// Helper method to mark all form controls as touched
private markFormGroupTouched(formGroup: FormGroup) {
  Object.values(formGroup.controls).forEach(control => {
    control.markAsTouched();
    if (control instanceof FormGroup) {
      this.markFormGroupTouched(control);
    }
  });
}

// Helper method for error handling
private handleError(message: string, error?: any) {
  this.isLoading = false;
  this.errorMessage = message;
  console.error(message, error);
  
  // Clear error after 5 seconds
  setTimeout(() => {
    if (this.errorMessage === message) {
      this.errorMessage = '';
    }
  }, 5000);
}
  private stripHtml(html: string): string {
    const tmp = document.createElement('div');
    tmp.innerHTML = html;
    return tmp.textContent || tmp.innerText || '';
  }

  private slugify(text: string): string {
    return text.toLowerCase().trim().replace(/[\s\W-]+/g, '-').replace(/^-+|-+$/g, '');
  }
}