import {Book, DamageLogger, Librarian} from './interfaces';
import {Category} from "./enums";
import {Encyclopedia, ReferenceItem, UniversityLibrarian} from "./classes";

function GetAllBooks(): Book[] {
  const books = [
    {
      author: 'James Joyce',
      available: true,
      category: Category.Fiction,
      id: 1,
      title: 'Ulysses',
    },
    {
      author: 'Ernest Hemingway',
      available: false,
      category: Category.Fiction,
      id: 2,
      title: 'A farewall to arms',
    },
    {
      author: 'Maya Angelou',
      available: true,
      category: Category.Poetry,
      id: 3,
      title: 'I know why the caged bird sings',
    },
    {
      author: 'Herman Melville',
      available: true,
      category: Category.Fiction,
      id: 4,
      title: 'Moby Dick',
    }
  ];

  return books;
}

function LogFirstAvailable(books = GetAllBooks()): void {

  const numberOfBooks: number = books.length;
  let firstAvailable: string = '';
  for (let currentBook of books) {
    if (currentBook.available) {
      firstAvailable = currentBook.title;
      break;
    }
  }

  console.log(`Total number of books: ${numberOfBooks}.`);
  console.log(`First available: ${firstAvailable}.`);
}

function CheckoutBooks(customer: string, ...bookIds: number[]): string[] {
  console.log(`Checking out books for ${customer}.`);

  let booksCheckedOut: string[] = [];
  for (let id of bookIds) {
    let book = GetBookById(id);
    if (book.available) {
      booksCheckedOut.push(book.title);
    }
  }

  return booksCheckedOut;
}

function CreateCustomer(name: string, age?: number, city?: string) {
  console.log(`Name: ${name}.`);
  if (age) {
    console.log(`Age: ${age}.`);
  }
  if (city) {
    console.log(`City: ${city}.`);
  }
}

function CreateCustomerId(chars: string, nums: number): string {
  return chars + nums;
}

function GetBookTitlesByCategory(categoryFilter: Category = Category.Fiction): Array<string> {
  console.log(`Getting books in category: ${Category[categoryFilter]}.`);

  const allBooks = GetAllBooks();
  const filteredTitles: string[] = [];

  for (let currentBook of allBooks) {
    if (currentBook.category === categoryFilter) {
      filteredTitles.push(currentBook.title);
    }
  }
  return filteredTitles;
}

function GetBookById(id: number): Book {
  const allBooks = GetAllBooks();
  return allBooks.filter(book => book.id === id)[0];
}

function LogBookTitles(titles: string[]): void {
  for (let title of titles) {
    console.log(title);
  }
}

// Note: no implementation.
function GetTitles(author: string): string[];
function GetTitles(available: boolean): string[];
// Now an implementation:
function GetTitles(bookProperty: any): string[] {
  const allBooks = GetAllBooks();

  const foundTitles: Array<string> = [];
  if (typeof bookProperty == 'string') {
    //  get books by author, add to foundTitles
    for (let book of allBooks) {
      if (book.author === bookProperty) {
        foundTitles.push(book.title);
      }
    }
  }
  else if (typeof bookProperty === 'boolean') {
    // get available books, add to foundTitles
    for (let book of allBooks) {
      if (book.available === bookProperty) {
        foundTitles.push(book.title);
      }
    }
  }
  else {
    throw new Error('Invalid property type: ' + typeof bookProperty);
  }

  return foundTitles;
}

function PrintBook(book: Book): void {
  console.log(`${book.title} by ${book.author}.`);
}

//******************************************************************************

let myBook: Book = {
  author: 'Jane Austen',
  available: true,
  category: Category.Fiction,
  // copies: 3,
  id: 5,
  pages: 250,
  title: 'Pride and prejudice',
  // year: '1813',
  markDamaged: reason => console.log(`Damaged: ${reason}.`),
};

// PrintBook(myBook);
// myBook.markDamaged('Torn back cover');

// let logDamage: DamageLogger = reason => console.log(`Damage reported: ${reason}.`);
// logDamage('Coffee stains');

// let favoriteLibrarian: Librarian = new UniversityLibrarian();
// favoriteLibrarian.name = 'Sharon';
// favoriteLibrarian.assistCustomer('Lynda');

// let ref: ReferenceItem = new ReferenceItem('Facts and Figures', 2016);
// ref.publisher = 'Random Data publisher';
// ref.printItem();
// console.log(ref.publisher);

let refBook = new Encyclopedia('WorldPedia', 1900, 10);
refBook.printItem();