import { ChangeDetectorRef, Component, ElementRef, OnDestroy, OnInit, ViewChild } from '@angular/core';
import { Router } from '@angular/router';
import { Capacitor } from '@capacitor/core';
import { Keyboard } from '@capacitor/keyboard';
import { IonPopover, IonTextarea, IonicModule, ModalController, NavController, Platform, PopoverController } from '@ionic/angular';
import { Subject, takeUntil } from 'rxjs';

import { NgClass, NgFor, NgIf } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { api } from '@enums/api.enum';
import { constants } from '@enums/constants.enum';
import { GJainStorage } from '@enums/gjain-storage.enum';
import { Roots } from '@enums/root.enum';
import { PostList, Privacy, ProfileData, ProfileResponse } from '@interfaces/common';
import { TaggedUserPage } from '@pages/post/tagged-user/tagged-user.page';
import { SafeUrlPipe } from '@pipes/safe-url.pipe';
import { AlertService } from '@services/alert.service';
import { CameraGalleryService } from '@services/camera-gallery.service';
import { HttpRequestService } from '@services/http-request.service';
import { StateManagementService } from '@services/state-management.service';
import { UtilityService } from '@services/utility.service';

const SANGH_POST_TYPE = 3;
@Component({
  selector: 'app-post-feed',
  templateUrl: './post-feed.page.html',
  styleUrls: ['./post-feed.page.scss'],
  standalone: true,
  imports: [IonicModule, NgClass, NgIf, FormsModule, NgFor, SafeUrlPipe]
})
export class PostFeedPage implements OnInit, OnDestroy {
  @ViewChild('fileInput', { static: true }) fileInput: ElementRef;
  @ViewChild('personalLocation') personalLocation: ElementRef;
  @ViewChild('text') textElement: IonTextarea;
  @ViewChild('mentionsPopover') mentionsPopover: IonPopover;
  updatePhotos = []; // images which uploaded at update time
  imageArray = [];   //images which uploaded at create time
  removeImageId = []; // id of image which are removed at update time
  userList = [];
  tagUserList = [];
  description = '';
  postPrivacy = 1; // 1 for public , 2 for private
  location: string;
  locationLat: string;
  locationLong: string;
  isUpdate = false;
  isDraft = false;
  statusCode: number;
  tagUserInput: string;
  post: PostList;
  userProfileData: ProfileData;
  draftPost: any;
  postType = 'General';
  categoryId = null;
  privacyList: Privacy[] = constants.postPrivacy;
  privacyListSangh: Privacy[] = constants.postPrivacySangh;
  redirectTo: string;
  type_id: number;
  type: number;
  userAvatar: string;
  userName: string;
  uploadedFiles: string[] = [];
  selectedSangh: number[] = [];
  isSanghMember: number;
  openSantSangh = false;
  loaderSantSangh = false;
  santSanghList = [];
  mentions = [];
  mentionText: string;
  mentionTextIndex: number;
  prevValue: string;
  private destroy$ = new Subject();

  constructor(
    private alert: AlertService,
    private navCtrl: NavController,
    private modalController: ModalController,
    private stateManagementService: StateManagementService,
    private httpRequestService: HttpRequestService,
    private router: Router,
    private platform: Platform,
    private popoverCtrl: PopoverController,
    private cameraGalleryService: CameraGalleryService,
    private utilityService: UtilityService,
    private change: ChangeDetectorRef,
  ) {
    this.categoryId = 5;
  }

  async ngOnInit() {
    if (this.router.getCurrentNavigation().extras.state) {
      this.userAvatar = this.router.getCurrentNavigation().extras.state?.userAvatar;
      this.userName = this.router.getCurrentNavigation().extras.state?.userName;
      this.redirectTo = this.router.getCurrentNavigation().extras.state?.redirectTo;
      if (this.router.getCurrentNavigation().extras.state.isUpdate) {
        this.isUpdate = this.router.getCurrentNavigation().extras.state.isUpdate;
      }
      if (this.router.getCurrentNavigation().extras.state.postData) {
        this.post = this.router.getCurrentNavigation().extras.state.postData;
      }
      if (this.router.getCurrentNavigation().extras.state.type) {
        this.type = this.router.getCurrentNavigation().extras.state.type;
        if (this.type === SANGH_POST_TYPE) {
          this.privacyList = this.privacyListSangh;
        }
      }
      if (this.router.getCurrentNavigation().extras.state.type_id) {
        if (this.type === SANGH_POST_TYPE) {
          this.selectedSangh = [this.router.getCurrentNavigation().extras.state.type_id];
        } else {
          this.type_id = this.router.getCurrentNavigation().extras.state.type_id;
        }
      }
      if (this.router.getCurrentNavigation().extras.state.send) {
        this.handleSharedData();
      }
    }
    if (!this.isUpdate && this.type !== SANGH_POST_TYPE) {
      await this.getDraftPostList();
      if (this.draftPost.data) {
        this.isDraft = true;
        this.post = this.draftPost.data;
      }
    }
    const userData = await this.stateManagementService.storage.get(GJainStorage.userData);
    if (userData) {
      this.userProfileData = userData;
    } else {
      this.getProfileInfo();
    }

    if (this.stateManagementService?.imageArray?.length > 0) {
      this.stateManagementService?.imageArray.forEach((image) => {
        this.uploadedFiles.push(image.imgString);
        this.imageArray.push(image.itemImage);
      });
    }

    if (this.isUpdate || this.isDraft) {
      this.description = this.post.description ? this.post.description : '';
      this.postPrivacy = this.post.privacy;
      this.location = this.post.location;
      this.locationLat = this.post.lat;
      this.locationLong = this.post.long;
      this.statusCode = this.post.status;
      this.updatePhotos = this.post.post_images;
      this.uploadedFiles = this.post.post_images.map((img) => img.image_name);
      this.tagUserList = this.post.tag_users;
      this.categoryId = this.post.category_id;
      this.postType = this.post.category.name;
      this.type = this.post.type ? this.post.type : 1;
      this.type_id = this.post.type_id ? this.post.type_id : this.post.created_by.id;
      this.mentions = this.post.mentions;
    }
    this.stateManagementService.postTypeSubject.pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
      this.categoryId = res.id;
      this.postType = res.name;
    });
    this.stateManagementService.postSelectedSanghSubject.pipe(takeUntil(this.destroy$)).subscribe(res => {
      this.selectedSangh = res;
    });
    this.stateManagementService.postLocationSubject.pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
      this.location = res;
    });
    this.stateManagementService.postLocationLatSubject.pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
      this.locationLat = res;
    });
    this.stateManagementService.postLocationLongSubject.pipe(takeUntil(this.destroy$)).subscribe((res: any) => {
      this.locationLong = res;
    });
    this.changePostType();
  }

  ionViewDidEnter() {

    // ----
    const checkRouteLinkAndPop = () => {
      if (this.router.url === ('/' + Roots.page + '/' + Roots.postFeed)) {
        document.getElementById('trigger-button').click();
      } else {
        this.navCtrl.pop();
      }
    };

    if (this.platform.is('android')) {
      this.platform.backButton.subscribeWithPriority(0, async () => {
        if (this.popoverCtrl.getTop()) {
          const modal = await this.popoverCtrl.getTop();
          if (modal) {
            this.popoverCtrl.dismiss();
            return;
          } else {
            checkRouteLinkAndPop();
          }
        } else {
          checkRouteLinkAndPop();
        }
      });
    }

    if (Capacitor.isPluginAvailable('Keyboard')) {
      Keyboard.addListener('keyboardWillHide', () => {
        this.openSantSangh = false;
        this.change.detectChanges();
      });
    }
  }

  getProfileInfo() {
    this.httpRequestService.get(api.shravakProfile).then((res: ProfileResponse) => {
      this.userProfileData = res.data;
      this.stateManagementService.userProfileData = res.data;
      this.stateManagementService.storage.set(GJainStorage.profileData, res.data);
    });
  }

  async getDraftPostList() {
    try {
      this.draftPost = await this.httpRequestService.get(api.draftPostList);
      this.isSanghMember = this.draftPost.is_sangh_member;
    } catch (e) {
      console.log(e);
    }
  }

  async handleSharedData() {
    if (this.stateManagementService.shareData?.length) {
      for (const item of this.stateManagementService.shareData) {
        if (decodeURIComponent(item.type) === 'text/plain') {
          this.description = this.platform.is('android') ? decodeURIComponent(item.url) : decodeURIComponent(item.title);
        } else if (decodeURIComponent(item.type).startsWith('image/')) {
          const image = await this.cameraGalleryService.resolveURL(decodeURIComponent(item.webPath));
          this.validateAndAddImage(image);
        }
      }
    }
  }

  validateAndAddImage(image: { imgString: any; itemImage: any }) {
    if (this.uploadedFiles.length === 3) {
      this.alert.showToasterError('Max 3 image can be uploaded');
      return;
    }

    const imageSize = image.itemImage.size / 1048576; // in MB
    if (imageSize > 10) {
      this.alert.showToasterError('Image size must be less than 10Mb');
      return;
    }

    if ((imageSize <= 10) && (this.uploadedFiles.length < 3)) {
      this.uploadedFiles.push(image.imgString);
      this.imageArray.push(image.itemImage);
    }
  }

  selectImages() {
    this.cameraGalleryService.selectMultipleImage(512, 512, false).then((imageData: Array<{ imgString: string; itemImage: Blob }>) => {
      if (imageData && imageData.length > 0) {
        imageData.forEach((image) => {
          this.validateAndAddImage(image);
        });
      }
    });
  }

  removeImage(index) {
    this.uploadedFiles.splice(index, 1);
    if (index < this.updatePhotos.length) {
      this.removeImageId.push(this.updatePhotos[index].id);
      this.updatePhotos.splice(index, 1);
    } else {
      this.imageArray.splice(index, 1);
    }
  }

  getUserList(event) {
    if (!event.value.trim()) {
      return this.userList = [];
    }
    const isSameStr = this.utilityService.isSameStr(event.value, this.prevValue, true);
    this.prevValue = event.value;
    if (!isSameStr) {
      const params = {
        name: event.value.trim(),
        already_tagged: this.tagUserList.map(ele => ele.id)
      };
      const apiRoute = (+this.type === SANGH_POST_TYPE) ? api.userList : api.friendList;
      this.httpRequestService.post(apiRoute, params).then((res: any) => {
        this.userList = res.data;
      });
    }
  }

  tagUser(user) {
    this.tagUserList.push(user);
    this.tagUserInput = '';
    this.userList = [];
  }

  createPost(statusCode) {
    this.statusCode = statusCode;
    let errMsg = '';
    if (!(this.description || this.imageArray.length !== 0 || this.updatePhotos.length !== 0)) {
      errMsg = 'Please add any image or write something you want to share';
    } else if (!this.categoryId) {
      errMsg = 'Please select post type';
    } else if (this.type === SANGH_POST_TYPE && this.selectedSangh.length === 0) {
      errMsg = 'Please select sangh';
    }

    if (errMsg) {
      this.alert.showToasterError(errMsg);
      return;
    }

    const formData = new FormData();
    formData.append('description', this.description);
    formData.append('privacy', this.postPrivacy.toString());
    formData.append('category_id', this.categoryId);
    formData.append('type', this.type.toString());
    formData.append('type_id', this.type === SANGH_POST_TYPE ? this.selectedSangh.join(',') : this.type_id.toString());
    if (this.location) { formData.append('location', this.location); }
    if (this.locationLat) { formData.append('latitude', this.locationLat); }
    if (this.locationLong) { formData.append('longitude', this.locationLong); }
    for (const [index, image] of this.imageArray.entries()) {
      formData.append(`images[${index}]`, image);
    }
    if (this.tagUserList) {
      for (const [index, user] of this.tagUserList.entries()) {
        formData.append(`user_id[${index}]`, user.id);
      }
    }
    const currentlyMentioned = this.utilityService.extractMentionedNames(this.description, this.mentions);
    if (currentlyMentioned.length) {
      for (const [index, item] of currentlyMentioned.entries()) {
        formData.append(`mentions[${index}][id]`, item.id);
        formData.append(`mentions[${index}][type]`, item.type);
      }
    }
    formData.append('status', this.statusCode.toString());
    this.alert.showSpinner();
    if (this.isUpdate || this.isDraft) {
      for (const [index, imageId] of this.removeImageId.entries()) {
        formData.append(`removed_image_id[${index}]`, imageId);
      }
      this.httpRequestService.post(api.updatePost + '/' + this.post.id, formData).then((res: any) => {
        this.alert.showToaster(res.message);
      }).finally(() => {
        this.alert.hideLoader();
        this.mentions = [];
        this.redirectToPage(this.redirectTo);
      });
    } else {
      this.httpRequestService.post(api.createPost, formData).then((res: any) => {
        this.alert.showToaster(res.message);
        if (+statusCode === 1) {
          this.modalController.dismiss();
        }
      }).finally(() => {
        this.alert.hideLoader();
        this.mentions = [];
        this.redirectToPage(this.redirectTo);
      });
    }
  }

  moveToPostType() {
    const navOption = {
      state: {
        postType: this.categoryId ? this.categoryId : null,
        isUpdate: this.isUpdate,
        type: this.type
      },
    };
    this.navCtrl.navigateForward(Roots.page + '/' + Roots.postType, navOption);
  }

  goToSelectSangh() {
    const navOption = {
      state: {
        selectedSangh: this.selectedSangh
      },
    };
    this.navCtrl.navigateForward(Roots.page + '/' + Roots.selectSangh, navOption);
  }

  redirectToPage(route) {
    this.navCtrl.navigateBack(route);
  }

  async onModelOpen(taggedUsers) {
    const componentProps = {
      taggedUsers
    };
    const modal = await this.modalController.create({
      component: TaggedUserPage,
      componentProps,
      mode: 'ios',
      backdropDismiss: true,
      breakpoints: [0.1, 0.6, 1],
      initialBreakpoint: 0.6,
    });
    return await modal.present();
  }

  continueEditing() {
    this.modalController.dismiss();
  }

  discardPost() {
    this.modalController.dismiss();
    if (this.isDraft) {
      this.removeFromDraft();
    }
    this.redirectToPage(this.redirectTo);
  }

  removeFromDraft() {
    this.alert.showSpinner();
    this.httpRequestService.delete(api.deletePost + '/' + this.post.id).then(() => {
      this.alert.showToaster('Post removed from draft successfully.');
    }).finally(() => {
      this.alert.hideLoader();
    });
  }

  addLocation() {
    const navOption = {
      state: {
        addLocation: this.location ? this.location : '',
        addLocationLat: this.locationLat ? this.locationLat : '',
        addLocationLong: this.locationLong ? this.locationLong : '',
        type: this.type,
      },
    };
    this.navCtrl.navigateForward(Roots.page + '/' + Roots.addLocation, navOption);
  }

  changePostType() {
    this.stateManagementService.postTypeSubject.next(this.type === SANGH_POST_TYPE ? {
      id: 1,
      name: 'Dharmik'
    } : {
      id: 5,
      name: 'General',
    });
  }

  searchSantSangh(str: string) {
    this.loaderSantSangh = true;
    this.httpRequestService
      .post(api.globalSearch, {
        name: str
      })
      .then((res: any) => {
        this.santSanghList = res.data;
        if (!this.santSanghList.length) { this.openSantSangh = false; }
      }).finally(() => {
        this.loaderSantSangh = false;
      });
  }

  async scanText() {
    if (!this.description) {
      this.openSantSangh = false;
      return false;
    }

    const textarea = await this.textElement.getInputElement();
    const startIndex = this.description.lastIndexOf('@', textarea.selectionStart - 1);

    if (startIndex !== -1) {
      this.mentionText = this.description.substring(startIndex, textarea.selectionEnd);
      this.mentionTextIndex = startIndex;
      const wordHasAtSign = this.utilityService.extractWordsAfterAtSign(this.mentionText);
      if (wordHasAtSign) {
        this.openSantSangh = true;
        this.searchSantSangh(wordHasAtSign.substring(1));
      } else {
        this.openSantSangh = false;
      }
    }
  }

  async appendToMessage(item: any) {
    if (!this.mentions.some(i => i.id === item.id && i.name === item.name && i.type === item.type)) {
      this.mentions.push((({ id, name, type }) => ({ id, name, type }))(item));
    }

    this.description = this.description.slice(0, this.mentionTextIndex) +
      this.description.slice(this.mentionTextIndex).replace(this.mentionText, '@' + item.name + ' ');

    this.openSantSangh = false;
    this.textElement.setFocus();
  }

  ionViewDidLeave() {
    this.stateManagementService.imageArray = [];
    this.stateManagementService.shareData = null;
    this.stateManagementService.userSanghList = [];
  }

  ngOnDestroy() {
    this.destroy$.next(true);
    this.destroy$.complete();
  }

}
