import { AfterViewInit, Component, OnInit } from '@angular/core';
import { BaseService } from 'src/app/shared/service/base.service';
import * as L from 'leaflet';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ToastService } from 'src/app/toast/toast-service';
import * as JsBarcode from 'jsbarcode';
interface Book {
  id: number;
  title: string;
  author: string;
  category: string;
  language: string;
  publisher: string;
  rack: string;
  totalCount: number;
  availableCount: number;
}

delete (L.Icon.Default.prototype as any)._getIconUrl;

L.Icon.Default.mergeOptions({
  iconRetinaUrl: 'assets/marker-icon-2x.png',
  iconUrl: 'assets/marker-icon.png',
  shadowUrl: 'assets/marker-shadow.png'
});

@Component({
  selector: 'app-default',
  templateUrl: './default.component.html',
  styleUrls: ['./default.component.scss']
})
export class DefaultComponent implements OnInit, AfterViewInit {
  breadCrumbItems: Array<{}> = [];
  isStudent: boolean = false;
  userId: any;
  currentUserName: string | null ;

  constructor(private baseService: BaseService,    private fb: FormBuilder, private toastService: ToastService
  ) {}

  /* ================= TOP SUMMARY CARDS ================= */
  cards = [
    {
      label: 'Book Titles',
      value: '0',
      icon: 'bx bx-book-open',
      theme: 'blue'
    },
    {
      label: 'Issued Books',
      value: '0',
      icon: 'bx bx-book-content',
      theme: 'orange'
    },
    {
      label: 'Overdue Books',
      value: '0',
      icon: 'bx bx-error-circle',
      theme: 'red'
    },
    {
      label: 'Total Copies',
      value: '0',
      icon: 'bx bx-group',
      theme: 'green'
    }
  ];

  /* ================= FILTER ================= */
  months = [
    { name: 'Jan', value: 1 },
    { name: 'Feb', value: 2 },
    { name: 'Mar', value: 3 },
    { name: 'Apr', value: 4 },
    { name: 'May', value: 5 },
    { name: 'Jun', value: 6 },
    { name: 'Jul', value: 7 },
    { name: 'Aug', value: 8 },
    { name: 'Sep', value: 9 },
    { name: 'Oct', value: 10 },
    { name: 'Nov', value: 11 },
    { name: 'Dec', value: 12 }
  ];

  filter: any = {
    month: new Date().getMonth() + 1,
    fromDate: '',
    toDate: ''
  };

  // copies: any[] = [];

// pagination
copiesPage = 1;
copiesPageSize = 5;

  /* ================= EXISTING API DATA ================= */
  transactions: any[] = [];
  // transactions: any[] = [];
filteredTransactions: any[] = [];

// pagination
txPage = 1;
txPageSize = 5;
txPageSizeOptions = [5, 10, 20];

  /* ================= STATIC ADMIN DATA ================= */
  bookSearch: string = '';

  manageBooks = [
    { id: 1, bookName: 'Harry Potter', category: 'Fiction', author: 'J.K. Rowling', status: 'ISSUED' },
    { id: 2, bookName: 'Science Guide', category: 'Science', author: 'R. Sharma', status: 'AVAILABLE' },
    { id: 3, bookName: 'History of India', category: 'History', author: 'Bipan Chandra', status: 'ISSUED' },
    { id: 4, bookName: 'Maths Basics', category: 'Science', author: 'R.D. Sharma', status: 'AVAILABLE' },
    { id: 5, bookName: 'Oliver Twist', category: 'Fiction', author: 'Charles Dickens', status: 'AVAILABLE' }
  ];

  // recentActivities = [
  //   { icon: 'bx bx-book-open', theme: 'blue', text: 'Issued Physics Basics' },
  //   { icon: 'bx bx-check-circle', theme: 'green', text: 'Returned Maths Guide' },
  //   { icon: 'bx bx-bookmark-plus', theme: 'orange', text: 'New books added in Fiction category' },
  //   { icon: 'bx bx-book', theme: 'blue', text: 'Wings of Fire' },
  //   { icon: 'bx bx-rupee', theme: 'orange', text: 'Aryan Sharma paid +50 fine.' }
  // ];

  overdueSummary = {
    pending: 210,
    collected: 150,
    waived: 90
  };


  recentFines = [
    { name: 'Aryan Sharma', book: 'Ticbay', amount: 30, time: 'Today' },
    { name: 'Priya Agriyal', book: 'Yesamby', amount: 30, time: 'Yesterday' },
    { name: 'Varun Joshi', book: 'History of India', amount: 20, time: '2 days ago' }
  ];

  fineCollections = [
    { label: 'This Month', issued: 238, collected: 355 },
    { label: 'Last Month', issued: 255, collected: 240 }
  ];

  libraryFineRows = [
    { title: 'Tony', issued: 238, fine: 210, width: 82 },
    { title: 'Requested', issued: 210, fine: 210, width: 70 }
  ];

  /* ================= CHARTS ================= */
  finesBarChart: any = {};
  finesPieChart: any = {};

  /* ================= STUDENT ================= */
  studentData: any = {
     "current": 3,
        "dueSoon": 0,
        "finePending": 400.0,
        "returned": 4
  };

  studentBooks: any[] = [];
  studentPie: any = {};
  books: any[] = [];
filteredBooksV: any[] = [];

search: any = {
  title: '',
  category: '',
  author: '',
  language: '',
  publisher: ''
};

statistics: any = {
  newBooks: 0,
  growth: 0,
  overduePending: 0,
  finesPending: 0,
  reservedBooks: 0
};

recentActivities_students: any[] = [];
isStatsLoading = true;

getStatistics() {
  this.isStatsLoading = true;

  this.baseService.getData("api/dashboard/statistics").subscribe({
    next: (res: any) => {
      const data = res.data || {};

      this.statistics = {
        newBooks: data.newBooks || 0,
        growth: data.growth || 0,
        overduePending: data.overduePending || 0,
        finesPending: data.finesPending || 0,
        reservedBooks: data.reservedBooks || 0
      };

      this.isStatsLoading = false;
    },
    error: () => {
      this.isStatsLoading = false;
    }
  });
}

  ngOnInit() {
    const role = sessionStorage.getItem('role');
    this.userId = sessionStorage.getItem('user');
    this.currentUserName = localStorage.getItem('username');
    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.loadCategories(); 
        // this.loadBooks();
        this.loadRacks();
   this.getProfile()
    this.isStudent = role === 'STUDENT';
    this.breadCrumbItems = [{ label: 'LMS' }, { label: 'Dashboard', active: true }];

    if (this.isStudent) {
      this.loadStudentDashboard();
      this.getReadingProgress()
           this.getStudentBooks();
        this.getStudentSummary()

    } else {
      this.loadDashboard();
      this.loadTransactions();
      this.setStaticCharts();
       this.loadBooks();
       this.getRecentActivities();
  this.getOverdueDashboard();
  this.getStatistics()
    }

    this.updateDateTime();

  // ⏱ update time every minute
  setInterval(() => {
    this.updateDateTime();
  }, 60000);
  

  }
recentActivities: any[] = [];
getStudentSummary() {
  this.baseService.getData("api/dashboard/student-summary").subscribe({
    next: (res: any) => {
      this.studentData = res.data || {};
    },
    error: (err) => {
      console.error("Error fetching student summary", err);
      this.studentData = {};
    }
  });
}
getStudentBooks() {
  this.baseService.getData("api/dashboard/student-books").subscribe({
    next: (res: any) => {
      this.studentBooks = res.data || [];
      this.getActivity()

    },
    error: (err) => {
      console.error("Error fetching student books", err);
      this.studentBooks = [];
    }
  });
}
activity:any;

profile: any = {};
currentDateTime: string = '';
updateDateTime() {
  const now = new Date();

  const options: Intl.DateTimeFormatOptions = {
    weekday: 'long',
    day: '2-digit',
    month: 'long'
  };

  const datePart = now.toLocaleDateString('en-IN', options);
  const timePart = now.toLocaleTimeString('en-IN', {
    hour: '2-digit',
    minute: '2-digit',
    hour12: true
  });

  this.currentDateTime = `${datePart} | ${timePart}`;
}

getProfile() {
  this.baseService.getData('users/profile').subscribe({
    next: (res: any) => {
      this.profile = res.data || {};
      this.currentUserName = this.profile.name
    }
  });
}

getActivity() {
  this.activity = (this.studentBooks || [])
    .map((book: any) => {

      if (book.status === 'RETURNED') {
        return {
          text: `Returned "${book.title}"`,
          icon: 'bx bx-check',
          theme: 'green',
          time: book.returnedAt
        };
      }

      return {
        text: `Issued "${book.title}"`,
        icon: 'bx bx-book-add',
        theme: 'orange',
        time: book.issueDate
      };

    })
    .sort((a: any, b: any) =>
      new Date(b.time).getTime() - new Date(a.time).getTime()
    )
    .slice(0, 5);
}
readingProgress: any = {
  booksRead: 0,
  goal: 10,
  progress: 0,
  badges: []
};

getReadingProgress() {
  this.baseService.getData("api/dashboard/reading-progress").subscribe({
    next: (res: any) => {
      const data = res.data || {};

      this.readingProgress = {
        booksRead: data.booksRead || 0,
        goal: data.goal || 10,
        progress: data.progress || 0,
        badges: data.badges || []
      };
    }
  });
}


getIcon(type: string) {
  switch (type) {
    case 'ISSUED': return 'bx bx-book-open';
    case 'RETURNED': return 'bx bx-check-circle';
    case 'OVERDUE': return 'bx bx-exclamation-triangle';
    case 'NEW': return 'bx bx-plus-circle';
    default: return 'bx bx-info-circle';
  }
}

getTheme(type: string) {
  switch (type) {
    case 'ISSUED': return 'blue';
    case 'RETURNED': return 'green';
    case 'OVERDUE': return 'red';
    case 'NEW': return 'orange';
    default: return 'orange';
  }
}
getRecentActivities() {
  this.baseService.getData("api/dashboard/recent-activities").subscribe({
    next: (res: any) => {
      const data = res.data || [];

      this.recentActivities = data.map((item: any) => ({
        text: item.message || 'No activity',
        icon: this.getIcon(item.type),
        theme: this.getTheme(item.type)
      }));
    },
    error: (err) => {
      console.error('Error fetching activities', err);
      this.recentActivities = [];
    }
  });
}
  ngAfterViewInit() {}

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;
}
  page = 1;
pageSize = 5;

get paginatedBooks() {
  const start = (this.page - 1) * this.pageSize;
  return this.filteredBooksV.slice(start, start + this.pageSize);
}
get pages(): (number | string)[] {

  const total = this.totalPages;
  const current = this.page;

  if (total <= 5) {
    return Array.from({ length: total }, (_, i) => i + 1);
  }

  const pages: (number | string)[] = [];

  // first
  pages.push(1);

  // left dots
  if (current > 3) {
    pages.push('...');
  }

  // middle pages
  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;
}
get totalPages() {
  return Math.ceil(this.filteredBooksV.length / this.pageSize);
}
prevPage() {
  if (this.page > 1) {
    this.page--;
  }
}

nextPage() {
  if (this.page < this.totalPages) {
    this.page++;
  }
}
get startIndex(): number {
  return (this.page - 1) * this.pageSize + 1;
}

get endIndex(): number {
  const end = this.page * this.pageSize;
  return end > this.filteredBooksV.length
    ? this.filteredBooksV.length
    : end;
}
goToPage(p: number) {
  this.page = p;
}
  loadBooks() {

    this.baseService.getData('books')
      .subscribe((res: any) => {

        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();
      });

  }
  applyFilters() {
  this.filteredBooksV = this.books.filter((b: any) => {

    return (!this.search.title || b.title?.toLowerCase().includes(this.search.title.toLowerCase())) &&
           (!this.search.category || b.category?.toLowerCase().includes(this.search.category.toLowerCase())) &&
           (!this.search.author || b.author?.toLowerCase().includes(this.search.author.toLowerCase())) &&
           (!this.search.language || b.language?.toLowerCase().includes(this.search.language.toLowerCase())) &&
           (!this.search.publisher || b.publisher?.toLowerCase().includes(this.search.publisher.toLowerCase()));

  });
}

  onMonthChange() {
    this.loadTransactions();
  }

  onDateChange() {
    if (this.filter.fromDate || this.filter.toDate) {
      this.filter.month = '';
    }
    this.loadTransactions();
  }

  loadDashboard() {
  this.baseService.getData('api/dashboard').subscribe(
    (res: any) => {
      const d = res?.data || {};

      const totalBooks = d.totalBooks ?? 0;
      const availableBooks = d.availableBooks ?? 0;
      const totalStudents = d.totalStudents ?? 0;

      const issuedBooks =d.issuedBooks;
      const overdueBooks = d.overdueBooks ?? 0; // not in API → default 0

      this.cards[0].value = this.formatNumber(totalBooks);
      this.cards[1].value = this.formatNumber(issuedBooks);
      this.cards[2].value = this.formatNumber(overdueBooks);
      this.cards[3].value = this.formatNumber(availableBooks);
    },
    () => {
      // fallback → set ZERO (not random)
      this.cards.forEach(c => c.value = '0');
    }
  );
}

 loadTransactions() {
  let params: any = {};

  if (this.filter.month) params.month = this.filter.month;
  if (this.filter.fromDate) params.fromDate = this.filter.fromDate;
  if (this.filter.toDate) params.toDate = this.filter.toDate;

  this.baseService.getData('books/dashboard/transactions', params).subscribe(
    (res: any) => {
      this.transactions = res.data || [];
      this.filteredTransactions = [...this.transactions]; // 🔥 important
      this.txPage = 1;
    },
    () => {
      this.transactions = [];
      this.filteredTransactions = [];
    }
  );
}
tooltipVisible = false;
tooltipX = 0;
tooltipY = 0;
tooltipStay = false;

issuedTo: any = null;
showTooltip(copy: any, event: MouseEvent) {
  this.issuedTo = copy.user;

  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);
}
get paginatedTransactions() {
  const start = (this.txPage - 1) * this.txPageSize;
  return this.filteredTransactions.slice(start, start + this.txPageSize);
}

get txTotalPages() {
  return Math.ceil(this.filteredTransactions.length / this.txPageSize);
}

prevTxPage() {
  if (this.txPage > 1) this.txPage--;
}

nextTxPage() {
  if (this.txPage < this.txTotalPages) this.txPage++;
}

goToTxPage(p: number) {
  this.txPage = p;
}

get txStartIndex(): number {
  return (this.txPage - 1) * this.txPageSize + 1;
}

get txEndIndex(): number {
  const end = this.txPage * this.txPageSize;
  return end > this.filteredTransactions.length
    ? this.filteredTransactions.length
    : end;
}

onTxPageSizeChange(size: number) {
  this.txPageSize = size;
  this.txPage = 1;
}
get txPages(): (number | string)[] {

  const total = this.txTotalPages;
  const current = this.txPage;

  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;
}
  notifications: any[] = [];

  // studentBooks: any[] = [];
filteredStudentBooks: any[] = [];

// pagination
studentPage = 1;
studentPageSize = 5;

// search
studentSearch = '';

applyStudentFilter() {
  this.filteredStudentBooks = this.studentBooks.filter((b: any) =>
    !this.studentSearch ||
    b.title?.toLowerCase().includes(this.studentSearch.toLowerCase())
  );

  this.studentPage = 1; // reset page
}

get paginatedStudentBooks() {
  const start = (this.studentPage - 1) * this.studentPageSize;
  return this.filteredStudentBooks.slice(start, start + this.studentPageSize);
}

get studentTotalPages() {
  return Math.ceil(this.filteredStudentBooks.length / this.studentPageSize);
}

get studentPages(): number[] {
  return Array.from({ length: this.studentTotalPages }, (_, i) => i + 1);
}

prevStudentPage() {
  if (this.studentPage > 1) this.studentPage--;
}

nextStudentPage() {
  if (this.studentPage < this.studentTotalPages) this.studentPage++;
}

goToStudentPage(p: number) {
  this.studentPage = p;
}

get studentStartIndex(): number {
  return (this.studentPage - 1) * this.studentPageSize + 1;
}

get studentEndIndex(): number {
  const end = this.studentPage * this.studentPageSize;
  return end > this.filteredStudentBooks.length
    ? this.filteredStudentBooks.length
    : end;
}

getNotifications() {
  this.baseService.getData("api/dashboard/student-notifications").subscribe({
    next: (res: any) => {
      const data = res.data || [];

      this.notifications = data.map((item: any) => ({
        text: item.message,
        icon: this.getIcon(item.type),
        theme: this.getTheme(item.type)
      }));
    },
    error: () => {
      this.notifications = [];
    }
  });
}

  loadStudentDashboard() {
    this.baseService.getData(`api/dashboard/student?userId=${this.userId}`).subscribe((res: any) => {
      const d = res.data;

      // this.studentData = {
      //   total: d.total,
      //   current: d.current,
      //   returned: d.returned
      // };

      this.studentBooks = d.books;
      this.applyStudentFilter();

      this.studentPie = {
        series: d.categoryCount,
        chart: { type: 'pie', height: 260 },
        labels: d.categoryLabels
      };
    });
  }
//   overdueSummary: any = {
//   pending: 0,
//   collected: 0,
//   waived: 0
// };

// recentFines: any[] = [];

getOverdueDashboard() {
  this.baseService.getData("api/dashboard/overdue-summary").subscribe({
    next: (res: any) => {

      const data = res.data || {};

      this.overdueSummary = {
        pending: data.pending || 0,
        collected: data.collected || 0,
        waived: data.waived || 0
      };

      this.recentFines = (data.recentFines || []).map((item: any) => ({
        name: item.name,
        amount: item.amount,
        time: this.getTimeAgo(item.time)
      }));

      this.updateChart();
    }
  });
}
updateChart() {
   this.finesPieChart = {
      series: [
        this.overdueSummary.pending || 20,
        this.overdueSummary.collected || 40,
        this.overdueSummary.waived || 30
      ],
      chart: {
        type: 'pie',
        height: 250
      },
      labels: ['Pending', 'Collected', 'Waived'],
      legend: {
        position: 'bottom'
      },
      dataLabels: {
        enabled: true
      }
    };
}
getTimeAgo(date: string): string {
  const now = new Date();
  const past = new Date(date);

  const diff = Math.floor((now.getTime() - past.getTime()) / 1000);

  if (diff < 60) return 'Just now';
  if (diff < 3600) return Math.floor(diff / 60) + ' mins ago';
  if (diff < 86400) return Math.floor(diff / 3600) + ' hrs ago';

  return Math.floor(diff / 86400) + ' days ago';
}

  setStaticCharts() {
    this.finesBarChart = {
      series: [
        {
          name: 'Issued',
          data: [238, 255]
        },
        {
          name: 'Collected',
          data: [355, 240]
        }
      ],
      chart: {
        type: 'bar',
        height: 260,
        toolbar: { show: false }
      },
      plotOptions: {
        bar: {
          horizontal: false,
          columnWidth: '35%',
          borderRadius: 6
        }
      },
      dataLabels: {
        enabled: false
      },
      legend: {
        position: 'top'
      },
      xaxis: {
        categories: ['This Month', 'Last Month']
      },
      grid: {
        strokeDashArray: 4
      }
    };

    // this.finesPieChart = {
    //   series: [
    //     this.overdueSummary.pending,
    //     this.overdueSummary.collected,
    //     this.overdueSummary.waived
    //   ],
    //   chart: {
    //     type: 'pie',
    //     height: 250
    //   },
    //   labels: ['Pending', 'Collected', 'Waived'],
    //   legend: {
    //     position: 'bottom'
    //   },
    //   dataLabels: {
    //     enabled: true
    //   }
    // };
  }

  get filteredBooks() {
    if (!this.bookSearch) return this.manageBooks;

    return this.manageBooks.filter((book) =>
      book.bookName.toLowerCase().includes(this.bookSearch.toLowerCase())
    );
  }

  formatNumber(value: number): string {
    return new Intl.NumberFormat('en-IN').format(value);
  }

  getStatusClass(status: string): string {
    return status === 'ISSUED' ? 'status-issued' : 'status-available';
  }



  ////////////////////////////
  
  
  
    categories: string[] = ['Programming', 'Science', 'History'];
    statuses: string[] = ['All', 'Available', 'Low Stock'];
  
    selectedCategory = 'All';
    selectedStatus = 'All';
  
   
    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;
  
    /* ===================================================== */
  
    loadRacks(){
  
    this.baseService.getData('racks')
    .subscribe((res:any)=>{
  
      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;
  
    })
  
  }

  
    /* ===================================================== */
  
    openAddStock() {
  
      this.generatedBarcodes = [];
  
      this.stockForm.reset({
        copies: 1
      });
  
      this.showAddStockDialog = true;
    }
  
    /* ===================================================== */
  
    openInfo(book:any){
  
  this.selectedBook=book;
  
  this.copiesPage = 1; // 🔥 reset
 

  
  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.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){
  
    if(!copy?.id){
      this.toastService.show("Invalid copy");
      return;
    }
  
    this.baseService
      .postData(`books/issues/return/${copy.id}`, null)
      .subscribe(() => {
  
        this.toastService.show("Book returned");
  
        // refresh copies list
        if(this.selectedBook){
          this.openInfo(this.selectedBook);
        }
  
      });
  
  }
  
    /* ===================================================== */
  saveStock() {

  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();
  }
}