import { Component, OnInit } from '@angular/core';
import * as JsBarcode from 'jsbarcode';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { BaseService } from 'src/app/shared/service/base.service';
import { ToastService } from 'src/app/toast/toast-service';
import { LoaderService } from 'src/app/core/services/loader.service';

interface Book {
  id: number;
  title: string;
  author: string;
  category: string;
  language: string;
  publisher: string;
  rack: string;
  totalCount: number;
  availableCount: number;
}

@Component({
  selector: 'app-book-stock',
  templateUrl: './book-stock.component.html',
  styleUrls: ['./book-stock.component.scss']
})
export class BookStockComponent implements OnInit {

  books: Book[] = [];
  filteredBooks: Book[] = [];

  categories: string[] = ['Programming', 'Science', 'History'];
  statuses: string[] = ['All', 'Available', 'Low Stock'];

  selectedCategory = 'All';
  selectedStatus = 'All';

  search = {
    title: '',
    author: '',
    category: '',
    language: '',
    publisher: ''
  };

  showAddStockDialog = false;
  showInfoDialog = false;

  selectedBook: Book | null = null;
  generatedBarcodes: string[] = [];
racks:any[] = [];
shelves:any[] = [];
  stockForm!: FormGroup;
  copies:any[]=[];
users:any[]=[];

selectedCopy:any;

showIssuePopup=false;
showReturnPopup=false;
userRole:string=''
selectedUser: number | null = null;
dueDate:any;

  constructor(
    private fb: FormBuilder,
    private baseService: BaseService,
    private toastService: ToastService,
    private loader:LoaderService
  ) {}



// pagination
page = 1;
pageSize = 10; // default
pageSizeOptions = [10, 20, 30];

  ngOnInit() {
this.stockForm = this.fb.group({
  title: ['', Validators.required],
  author: ['', Validators.required],
  publisher: [''],

  category: ['', Validators.required],
  newCategory: [''],

  language: [''],

  rackId: [''],
  newRack: [''],

  shelfId: [''],
  newShelf: [''],

  copies: [1, [Validators.required, Validators.min(1)]]
});
    this.loadBooks();

     this.userRole = sessionStorage.getItem('role') || 'STUDENT';

     
  }
  copiesPage = 1;
copiesPageSize = 5;

get paginatedCopies() {
  if (!this.copies || !this.copies.length) return [];
  const start = (this.copiesPage - 1) * this.copiesPageSize;
  return this.copies.slice(start, start + this.copiesPageSize);
}

get copiesTotalPages() {
  return Math.ceil(this.copies.length / this.copiesPageSize);
}

get copiesStartIndex(): number {
  return (this.copiesPage - 1) * this.copiesPageSize + 1;
}

get copiesEndIndex(): number {
  const end = this.copiesPage * this.copiesPageSize;
  return end > this.copies.length ? this.copies.length : end;
}

prevCopiesPage() {
  if (this.copiesPage > 1) this.copiesPage--;
}

nextCopiesPage() {
  if (this.copiesPage < this.copiesTotalPages) this.copiesPage++;
}

goToCopiesPage(p: number) {
  this.copiesPage = p;
}

get copiesVisiblePages(): (number | string)[] {

  const total = this.copiesTotalPages;
  const current = this.copiesPage;

  if (total <= 6) {
    return Array.from({ length: total }, (_, i) => i + 1);
  }

  const pages: (number | string)[] = [];

  pages.push(1);

  if (current > 3) {
    pages.push('...');
  }

  const start = Math.max(2, current - 1);
  const end = Math.min(total - 1, current + 1);

  for (let i = start; i <= end; i++) {
    pages.push(i);
  }

  if (current < total - 2) {
    pages.push('...');
  }

  pages.push(total);

  return pages;
}


onPageSizeChange(size: number) {
  this.pageSize = size;
  this.page = 1; // reset
}
  get paginatedBooks() {
  const start = (this.page - 1) * this.pageSize;
  return this.filteredBooks.slice(start, start + this.pageSize);
}

get totalPages() {
  return Math.ceil(this.filteredBooks.length / this.pageSize);
}

get pages(): (number | string)[] {

  const total = this.totalPages;
  const current = this.page;

  if (total <= 6) {
    return Array.from({ length: total }, (_, i) => i + 1);
  }

  const pages: (number | string)[] = [];

  // first
  pages.push(1);

  // left dots
  if (current > 3) {
    pages.push('...');
  }

  // middle
  const start = Math.max(2, current - 1);
  const end = Math.min(total - 1, current + 1);

  for (let i = start; i <= end; i++) {
    pages.push(i);
  }

  // right dots
  if (current < total - 2) {
    pages.push('...');
  }

  // last
  pages.push(total);

  return pages;
}

prevPage() {
  if (this.page > 1) this.page--;
}

nextPage() {
  if (this.page < this.totalPages) this.page++;
}

goToPage(p: number) {
  this.page = p;
}

get startIndex(): number {
  return (this.page - 1) * this.pageSize + 1;
}

get endIndex(): number {
  const end = this.page * this.pageSize;
  return end > this.filteredBooks.length
    ? this.filteredBooks.length
    : end;
}

  /* ===================================================== */

  loadBooks() {

    this.loader.show()
    this.baseService.getData('books')
      .subscribe((res: any) => {
        if(this.userRole){
this.loadCategories(); 
    this.loadRacks();
     }

        if (!res?.data) return;

        this.books = res.data.map((b: any) => ({
          id: b.id,
          title: b.title,
          author: b.author,
          category: b.categoryName,
          language: '',
          publisher: b.publisher,
          rack: '',
          totalCount: b.totalCount,
          availableCount: b.availableCount
        }));

        this.applyFilters();
      });

  }

  /* ===================================================== */

  loadRacks(){

  this.baseService.getData('racks')
  .subscribe((res:any)=>{
    this.loader.hide()

    if(!res?.data) return;

    this.racks = res.data;

  })

}
onRackChange(){

  const rackId = this.stockForm.value.rackId;

  if(!rackId || rackId === 'OTHER'){
    this.shelves = [];
    return;
  }

  this.baseService.getData(`shelves/rack/${rackId}`)
  .subscribe((res:any)=>{

    if(!res?.data) return;

    this.shelves = res.data;

  })

}
applyFilters() {

  this.filteredBooks = this.books.filter(book => {

    const categoryMatch =
      this.selectedCategory === 'All' ||
      book.category === this.selectedCategory;

    const statusMatch =
      this.selectedStatus === 'All' ||
      (this.selectedStatus === 'Available' && book.availableCount > 1) ||
      (this.selectedStatus === 'Low Stock' && book.availableCount <= 1);

    return categoryMatch && statusMatch;

  });

}

  /* ===================================================== */

  openAddStock() {
this.loadCategories()
this.loadRacks()
    this.generatedBarcodes = [];

    this.stockForm.reset({
      copies: 1
    });

    this.showAddStockDialog = true;
  }

  /* ===================================================== */

  openInfo(book:any){

this.selectedBook=book;

this.baseService
.getData(`books/${book.id}/copies`)
.subscribe((res:any)=>{

this.copies=res.data;

});

this.showInfoDialog=true;

}
selectedUserType = 'STUDENT';

openIssuePopup(copy:any){

this.selectedCopy = copy;

this.showIssuePopup = true;

this.selectedUserType = 'STUDENT';

this.loadUsers();

this.dueDate = new Date(
Date.now() + 14*24*60*60*1000
).toISOString().split('T')[0];

}
onUserTypeChange(){
this.loadUsers();
}
onUserSelect(event:any){
  console.log("Selected User Event:", event);

  if(event){
    this.selectedUser = event;
  }
}
issueBook(){

let payload = {
  copyId: String(this.selectedCopy.id),
  userId: String(this.selectedUser),
  dueDate: String(this.dueDate)
};


this.baseService.postData("books/issues", new URLSearchParams(payload))
.subscribe(()=>{

this.toastService.show("Book issued");

this.showIssuePopup=false;
this.loadBooks()

this.openInfo(this.selectedBook);

});

}
loadUsers(){

if(this.selectedUserType === 'STUDENT'){

this.baseService.getData('students')
.subscribe((res:any)=>{

this.users = res.data.map((s:any)=>({

id: s.userId,

displayName:
s.admissionNumber + " - " +
s.firstName + " " + s.lastName

}));

});

}

else{

this.baseService.getData('staff')
.subscribe((res:any)=>{

this.users = res.data.map((s:any)=>({

id: s.userId,

displayName:
s.empCode + " - " +
s.firstName + " " + s.lastName

}));

});

}

}
returnBook(copy: any, finePaid: boolean = false) {

  this.baseService
    .postData(`books/issues/return/${copy.id}?finePaid=${finePaid}`, null)
    .subscribe((res: any) => {

      // 🔥 CASE 1: Fine Pending
      if (res.status === 'PENDING_FINE') {

        const fine = res.data.fine;

        if (confirm(`Fine ₹${fine}. Pay now?`)) {

          // 🔥 CALL AGAIN WITH finePaid = true
          this.returnBook(copy, true);
        }

        return;
      }

      // ✅ SUCCESS
      this.toastService.show("Book returned");

      this.loadBooks();

      if (this.selectedBook) {
        this.openInfo(this.selectedBook);
      }
    });
}

  /* ===================================================== */
//   saveStock(){

//   if(this.stockForm.invalid){
//     this.stockForm.markAllAsTouched();
//     return;
//   }

//   const v = this.stockForm.value;

//   let bookPayload:any = {
//     title: v.title,
//     author: v.author,
//     publisher: v.publisher
//   };

//   if(v.category === 'OTHER'){
//     bookPayload.newCategoryName = v.newCategory;
//   }
//   else{
//     bookPayload.categoryId = v.category;
//   }

//   this.baseService.postData('books', new URLSearchParams(bookPayload))
//   .subscribe((bookRes:any)=>{

//     const bookId = bookRes.data.id;

//     this.prepareRackShelf(v).then(location=>{

//       const copyPayload = {
//         copies: v.copies,
//         rackId: location.rackId,
//         shelfId: location.shelfId
//       };

//       this.baseService.postData(`books/${bookId}/copies`,
//         new URLSearchParams(copyPayload))
//       .subscribe((copyRes:any)=>{

//         this.generatedBarcodes = copyRes.data || [];

//         this.renderBarcodes();

//         this.toastService.show("Book Saved");

//         this.showAddStockDialog = false;

//         this.loadBooks();

//       })

//     })

//   })

// }
tooltipVisible = false;
tooltipX = 0;
tooltipY = 0;
tooltipStay = false;

issuedTo: any = null;

showTooltip(copy: any, event: MouseEvent) {
  this.issuedTo = copy.issuedTo;

  this.tooltipX = event.clientX + 10;
  this.tooltipY = event.clientY + 10;

  this.tooltipVisible = true;
}

hideTooltip() {
  setTimeout(() => {
    if (!this.tooltipStay) {
      this.tooltipVisible = false;
      this.selectedUser = null;
    }
    this.tooltipStay = false;
  }, 200);
}
saveStock() {

  this.loader.show();

  if (this.stockForm.invalid) {
    this.stockForm.markAllAsTouched();
    return;
  }

  const v = this.stockForm.value;

  let payload: any = {
    title: v.title,
    author: v.author,
    publisher: v.publisher
  };

  // CATEGORY
  if (v.category === 'OTHER') {
    payload.newCategoryName = v.newCategory;
  } else {
    payload.categoryId = v.category;
  }

  // RACK
  if (v.rackId === 'OTHER') {
    payload.newRack = v.newRack;
  } else {
    payload.rackId = v.rackId;
  }

  // SHELF
  if (v.shelfId === 'OTHER') {
    payload.newShelf = v.newShelf;
  } else {
    payload.shelfId = v.shelfId;
  }

  // 🔥 ONE API
  this.baseService.postData('books',
    new URLSearchParams(payload))
    .subscribe((res: any) => {

      const book = res.data.book;
      const rackId = res.data.rackId;
      const shelfId = res.data.shelfId;

      // 👉 NOW CALL COPIES API
      const copyPayload = {
        copies: v.copies,
        rackId: rackId,
        shelfId: shelfId
      };

      this.baseService.postData(`books/${book.id}/copies`,
        new URLSearchParams(copyPayload))
        .subscribe((copyRes: any) => {

          this.generatedBarcodes = copyRes.data || [];
          this.renderBarcodes();

          this.toastService.show("Book + Copies Added ✅");
          this.showAddStockDialog = false;

          this.loadBooks();
        });

    }, err => {
      this.toastService.show(err.error?.message || "Failed to save book ❌");
    });
}

  prepareRackShelf(v:any):Promise<any>{

  return new Promise(resolve=>{

    let rackId = v.rackId;
    let shelfId = v.shelfId;

    if(v.rackId === 'OTHER'){

      this.baseService.postData('racks',
        new URLSearchParams({name:v.newRack}))
      .subscribe((rackRes:any)=>{

        rackId = rackRes.data.id;

        if(v.shelfId === 'OTHER'){

          this.baseService.postData('shelves',
          new URLSearchParams({
            name:v.newShelf,
            rackId:rackId
          }))
          .subscribe((shelfRes:any)=>{

            shelfId = shelfRes.data.id;

            resolve({rackId,shelfId})

          })

        }
        else{

          resolve({rackId,shelfId})

        }

      })

    }
    else{

      resolve({rackId,shelfId})

    }

  })

}

  /* ===================================================== */

  renderBarcodes() {

    setTimeout(() => {

      this.generatedBarcodes.forEach(code => {

        JsBarcode(`#${code}`, code, {
          format: 'CODE128',
          width: 2,
          height: 60,
          displayValue: true
        });

      });

    });

  }

  /* ===================================================== */

  hasLowStock(book: Book): boolean {
    return book.availableCount <= 1;
  }

  /* ===================================================== */

  printBarcodes() {
    window.print();
  }
  loadCategories() {

  this.baseService.getData('categories')
    .subscribe((res: any) => {

      if (!res?.data) return;

      this.categories = res.data;

    });

}
generateBarcodes() {

  if (this.stockForm.invalid) return;

  const count = this.stockForm.value.copies;
  const base = Date.now();

  this.generatedBarcodes = [];

  for (let i = 0; i < count; i++) {
    this.generatedBarcodes.push(`TEMP${base}${i}`);
  }

  this.renderBarcodes();
}
}