#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include "administration.h"
#include "animal.h"
#include "terminal_io.h"
#include "file_element.h"


static void addTestData(Animal* animals, size_t* nrAnimals)
{
    Animal a1 = { 1, Dog, Male, 12, { 1, 2, 3 } };
    Animal a2 = { 2, Cat, Female, 4, { 4, 3, 2 } };
    Animal a3 = { 3, Parrot, Male, 40, { 8, 9, 10 } };
    Animal a4 = { 4, Dog, Female, 1, { 1, 1, 100 } };
    Animal a5 = { 5, GuineaPig, Male, 3, { 3, 4, 1 } };

    animals[(*nrAnimals)++] = a1;
    animals[(*nrAnimals)++] = a2;
    animals[(*nrAnimals)++] = a3;
    animals[(*nrAnimals)++] = a4;
    animals[(*nrAnimals)++] = a5;
}

int main(int argc, char* argv[])
{
    const size_t MaxNrAnimals = 20;
    Animal animals[MaxNrAnimals];
    size_t nrAnimals = 0;
    MenuOptions choice = MO_SHOW_ANIMALS;

    addTestData(animals, &nrAnimals);

    printf("PRC assignment 'Animal Shelter'\n"
           "-------------------------------------------");

    if (argc != 1)
    {
        fprintf(stderr, "%s: argc=%d\n", argv[0], argc);
    }

    while (choice != MO_QUIT)
    {
        printf("\n\nMENU\n====\n\n");
        choice = getMenuChoice();

        switch (choice)
        {
        case MO_SHOW_ANIMALS:
            printAnimals(animals, nrAnimals);
            break;
        case MO_ADD_ANIMAL:
        {
            Animal newAnimal;
            newAnimal.Id = getInt("Enter animal ID: ");
            newAnimal.Species = (Species)getLimitedInt("Enter species: ", SpeciesNames, sizeof(SpeciesNames) / sizeof(SpeciesNames[0]));
            newAnimal.Sex = (Sex)getLimitedInt("Enter sex: ", SexNames, sizeof(SexNames) / sizeof(SexNames[0]));
            newAnimal.Age = getInt("Enter age: ");
            newAnimal.DateFound = getDate("Enter date found: ");
            if (addAnimal(&newAnimal, animals, MaxNrAnimals, nrAnimals, &nrAnimals) == 0)
            {
                printf("Animal added successfully.\n");
            }
            else
            {
                printf("Failed to add animal.\n");
            }
            break;
        }
        case MO_REMOVE_ANIMAL:
        {
            int animalId = getInt("Enter animal ID to remove: ");
            size_t newNrAnimals;
            if (removeAnimal(animalId, animals, nrAnimals, &newNrAnimals) >= 0)
            {
                nrAnimals = newNrAnimals;
                printf("Animal removed successfully.\n");
            }
            else
            {
                printf("Failed to remove animal.\n");
            }
            break;
        }
        case MO_SORT_ANIMALS_BY_AGE:
            if (sortAnimalsByAge(animals, nrAnimals) == 0)
            {
                printf("Animals sorted by age successfully.\n");
            }
            else
            {
                printf("Failed to sort animals by age.\n");
            }
            break;
        case MO_SORT_ANIMALS_BY_YEAR_FOUND:
            if (sortAnimalsByYearFound(animals, nrAnimals) == 0)
            {
                printf("Animals sorted by year found successfully.\n");
            }
            else
            {
                printf("Failed to sort animals by year found.\n");
            }
            break;
        case MO_SORT_ANIMALS_BY_SEX:
            if (sortAnimalsBySex(animals, nrAnimals) == 0)
            {
                printf("Animals sorted by sex successfully.\n");
            }
            else
            {
                printf("Failed to sort animals by sex.\n");
            }
            break;
        case MO_FIND_ANIMAL:
        {
            int animalId = getInt("Enter animal ID to find: ");
            Animal foundAnimal;
            if (findAnimalById(animalId, animals, nrAnimals, &foundAnimal) == 1)
            {
                printf("Animal found:\n");
                printAnimals(&foundAnimal, 1);
            }
            else
            {
                printf("Animal not found.\n");
            }
            break;
        }
        case MO_SAVE:
            if (writeAnimals("animals.dat", animals, nrAnimals) == 0)
            {
                printf("Animals saved to disk successfully.\n");
            }
            else
            {
                printf("Failed to save animals to disk.\n");
            }
            break;
        case MO_LOAD:
            if (readAnimals("animals.dat", animals, MaxNrAnimals) >= 0)
            {
                printf("Animals loaded from disk successfully.\n");
            }
            else
            {
                printf("Failed to load animals from disk.\n");
            }
            break;
        case MO_QUIT:
            break;
        default:
            printf("ERROR: invalid choice: %d\n", choice);
            break;
        }
    }
    return 0;
}
