#include "ui.h"
#include "../exceptions/exceptions.h"
#include "../domain/trench.h"
#include "../vector/vector.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

UI::UI(AdminController* adminController, UserController* userController){
    this->_adminController = adminController;
    this->_userController = userController;
}

UI::~UI(){
    delete this->_adminController;
    delete this->_userController;
}

void UI::run(){
    char option = 0;
    while(1){
        printf("1. Run as admin\n");
        printf("2. Run as user\n");
        printf("3. Exit\n");
        printf("Option: ");
        option = getchar();
        if(option == '\n' || getchar() != '\n'){
            while(getchar()!='\n');
            printf("Invalid option!\n");
            continue;
        }
        switch(option){
            case '1':
                this->runAsAdmin();
                break;
            case '2':
                this->runAsUser();
                break;
            case '3':
                return;
            default:
                printf("Invalid option!\n");
                break;
        }
    }
}

void UI::runAsAdmin(){
    char option = 0;
    while(1){
        printf("1. Add trench\n");
        printf("2. Remove trench\n");
        printf("3. Update trench\n");
        printf("4. List all trenches\n");
        printf("5. Exit\n");
        printf("Option: ");
        option = getchar();
        if(option == '\n' || getchar() != '\n'){
            while(getchar()!='\n');
            printf("Invalid option!\n");
            continue;
        }
        switch(option){
            case '1':
                {   
                    int check = 0;
                    char* buffer = new char[255];
                    int size;
                    char* colour = new char[255];
                    int price;
                    int quantity;
                    char* photograph = new char[255];
                    printf("Size: ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid price!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    size = atoi(buffer);
                    printf("Colour: ");
                    fgets(colour,255,stdin);
                    colour[strlen(colour)-1] = '\0';
                    if(strlen(colour)==0){
                        printf("Invalid colour!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    printf("Price: ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid price!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    price = atoi(buffer);
                    printf("Quantity: ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid quantity!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    quantity = atoi(buffer);
                    printf("Photograph: ");
                    fgets(photograph,255,stdin);
                    photograph[strlen(photograph)-1] = '\0';
                    if(strlen(photograph)==0){
                        printf("Invalid photograph!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    try{
                        this->_adminController->add(size,colour,price,quantity,photograph);
                        printf("Trench added!\n");
                    }
                    catch(AdminControllerException& e){
                        printf("%s\n",e.what());
                    }
                    catch(RepoException& e){
                        printf("%s\n",e.what());
                    }
                    delete[] buffer;
                    delete[] colour;
                    delete[] photograph;

                }
                break;
            case '2':
                {
                    int check = 0;
                    char* buffer = new char[255];
                    char size;
                    char* colour = new char[255];
                    char* photograph = new char[255];
                    printf("Size: ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid price!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    size = atoi(buffer);
                    printf("Colour: ");
                    fgets(colour,255,stdin);
                    colour[strlen(colour)-1] = '\0';
                    if(strlen(colour)==0){
                        printf("Invalid colour!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    printf("Photograph: ");
                    fgets(photograph,255,stdin);
                    photograph[strlen(photograph)-1] = '\0';
                    if(strlen(photograph)==0){
                        printf("Invalid photograph!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    try{
                        this->_adminController->remove(size,colour,photograph);
                        printf("Trench removed!\n");
                    }
                    catch(AdminControllerException& e){
                        printf("%s\n",e.what());
                    }
                    catch(RepoException& e){
                        printf("%s\n",e.what());
                    }
                    delete[] buffer;
                    delete[] colour;
                    delete[] photograph;
                }
                break;
            case '3':
                {
                    int check = 0;
                    char* buffer = new char[255];
                    char size;
                    char* colour = new char[255];
                    int price;
                    int quantity;
                    char* photograph = new char[255];
                    printf("Size: ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid price!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    size = atoi(buffer);
                    printf("Colour: ");
                    fgets(colour,255,stdin);
                    colour[strlen(colour)-1] = '\0';
                    if(strlen(colour)==0){
                        printf("Invalid colour!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    printf("Price: (type enter to not change it) ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid price!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    if (strlen(buffer)!=0)
                        price = atoi(buffer);
                    else 
                        price = -1;
                    printf("Quantity: (type enter to not change it) ");
                    fgets(buffer,255,stdin);
                    buffer[strlen(buffer)-1] = '\0';
                    for(size_t i=0;i<strlen(buffer);i++){
                        if(buffer[i]<'0' || buffer[i]>'9'){
                            check=1;
                            break;
                        }
                    }
                    if(check==1){
                        printf("Invalid quantity!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    check = 0;
                    if (strlen(buffer)!=0)
                        quantity = atoi(buffer);
                    else
                        quantity = -1;
                    printf("Photograph: ");
                    fgets(photograph,255,stdin);
                    photograph[strlen(photograph)-1] = '\0';
                    if(strlen(photograph)==0){
                        printf("Invalid photograph!\n");
                        delete[] buffer;
                        delete[] colour;
                        delete[] photograph;
                        continue;
                    }
                    try{
                        this->_adminController->update(size,colour,price,quantity,photograph);
                        printf("Trench updated!\n");
                    }
                    catch(AdminControllerException& e){
                        printf("%s\n",e.what());
                    }
                    catch(RepoException& e){
                        printf("%s\n",e.what());
                    }
                    delete[] buffer;
                    delete[] colour;
                    delete[] photograph;
                }
                break;
            case '4':
                for(Trench* i:*this->_adminController->getAll()){
                    char* s = i->toString();
                    printf("%s\n",s);
                    delete[] s;
                }
                break;
            case '5':
                return;
            default:
                printf("Invalid option!\n");
                break;
        }
    }
}

void UI::runAsUser(){
    char option;
    while(1){
        printf("1. Show all trench coats in a given size\n");
        printf("2. Show shopping cart\n");
        printf("3. Exit\n");
        printf("Option: ");
        option = getchar();
        if(option == '\n' || getchar() != '\n'){
            while(getchar()!='\n');
            printf("Invalid option!\n");
            continue;
        }
        switch(option){
            case '1':
            {
                int check = 0;
                char* buffer = new char[255];
                int size;
                printf("Size: ");
                fgets(buffer,255,stdin);
                buffer[strlen(buffer)-1] = '\0';
                for(size_t i=0;i<strlen(buffer);i++){
                    if(buffer[i]<'0' || buffer[i]>'9'){
                        check=1;
                        break;
                    }
                }
                if(check==1){
                    printf("Invalid size!\n");
                    delete[] buffer;
                    continue;
                }
                if (strlen(buffer)!=0)
                    size = atoi(buffer);
                else
                    size = -1;
                delete[] buffer;
                Vector<Trench*> iterator = this->_userController->getTrenchCarousel(size);
                if(iterator.size()==0){
                    printf("No trench coats found!\n");
                    continue;
                }
                int exit = 1;
                int index = 0;
                while(exit && iterator.size()){
                    char* s = iterator[index]->toString();
                    printf("%s\n",s);
                    printf("Total price: %d\n",this->_userController->shoppingListTotal());
                    delete[] s;
                    char option;

                    printf("1. Add to shopping cart\n");
                    printf("2. Next trench coat\n");
                    printf("3. Show picture\n");
                    printf("4. Exit\n");
                    printf("Option: ");
                    option = getchar();
                    if(option == '\n' || getchar() != '\n'){
                        while(getchar()!='\n');
                        printf("Invalid option!\n");
                        continue;
                    }
                    switch(option){
                        case '1':
                        {
                            this->_userController->addProductToShoppingList(iterator[index]);
                            if (iterator[index]->quantity() == 0){
                                iterator.remove(index);
                                if(index==iterator.size())
                                    index=0;
                            }
                            break;
                        }
                        case '2':
                        {
                            index++;
                            if(index==iterator.size())
                                index=0;
                            break;
                        }
                        case '3':
                        {
                            char* photograph = iterator[index]->photograph();
                            char* command = new char[1000];
                            strcpy(command,"open ");
                            strcat(command,photograph);
                            strcat(command," > /dev/null 2> /dev/null");
                            system(command);
                            delete[] command;
                            break;
                        }
                        case '4':
                        {
                            exit=0;
                            break;
                        }

                    }
                    
                
                }
                break;
            }
            case '2':
            {   if(this->_userController->getShoppingListTrench().size()==0){
                    printf("Shopping cart is empty!\n");
                    break;
                }
                printf("Total price: %d\n",this->_userController->shoppingListTotal());

                for(Trench* i:this->_userController->getShoppingListTrench()){
                    char* s = i->toString();
                    printf("%s",s);
                    delete[] s;
                }
                char option;
                while(1){
                    printf("1. Buy trench coats\n");
                    printf("2. Empty shopping cart\n");
                    printf("3. Exit\n");
                    printf("Option: ");
                    option = getchar();
                    if(option == '\n' || getchar() != '\n'){
                        while(getchar()!='\n');
                        printf("Invalid option!\n");
                        continue;
                    }
                    switch(option){
                        case '1':
                        {
                            this->_userController->buyShoppingList();
                            break;
                        }
                        case '2':
                        {
                            this->_userController->emptyShoppingList();
                            break;
                        }
                        case '3':
                        {
                            break;
                        }
                        default:
                        {
                            printf("Invalid option!\n");
                            break;
                        }
                    }
                    if('1'<=option && option<='3')
                        break;
                }
                break;
            }
            case '3':
            {
                return;
            }
        }
    }
}

