#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define MAX 256

typedef struct {
    char pergunta[MAX];
    char resposta[MAX];
} Conhecimento;

typedef struct Node {
    Conhecimento dado;
    struct Node *next;
} Node;

Node* criar_node(Conhecimento c) {
    Node *novo = (Node*)malloc(sizeof(Node));
    if (novo) {
        novo->dado = c;
        novo->next = NULL;
    }
    return novo;
}

void inserir(Node **head, Conhecimento c) {
    Node *novo = criar_node(c);
    if (*head == NULL) {
        *head = novo;
    } else {
        Node *temp = *head;
        while (temp->next != NULL)
            temp = temp->next;
        temp->next = novo;
    }
}

void salvar_conhecimento(Node *head) {
    FILE *fp = fopen("chatbot.dat", "wb");
    if (!fp) {
        printf("Erro ao abrir o arquivo para escrita!\n");
        return;
    }
    Node *temp = head;
    while (temp != NULL) {
        fwrite(&(temp->dado), sizeof(Conhecimento), 1, fp);
        temp = temp->next;
    }
    fclose(fp);
}

void carregar_conhecimento(Node **head) {
    FILE *fp = fopen("chatbot.dat", "rb");
    if (!fp) return; // Arquivo ainda não existe

    Conhecimento c;
    while (fread(&c, sizeof(Conhecimento), 1, fp)) {
        inserir(head, c);
    }
    fclose(fp);
}

void limpar_string(char *str) {
    for (int i = 0; str[i]; i++)
        str[i] = tolower(str[i]);
}

Node* buscar_resposta(Node *head, const char *pergunta) {
    Node *temp = head;
    char pergunta_lower[MAX];
    strcpy(pergunta_lower, pergunta);
    limpar_string(pergunta_lower);

    while (temp != NULL) {
        char temp_pergunta[MAX];
        strcpy(temp_pergunta, temp->dado.pergunta);
        limpar_string(temp_pergunta);
        if (strstr(pergunta_lower, temp_pergunta) != NULL) {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}

void aprender_resposta(Node **head, const char *nova_pergunta) {
    Conhecimento novo;
    strcpy(novo.pergunta, nova_pergunta);
    printf("Eu ainda não sei como responder...\n");
    printf("Por favor, me ensine: como devo responder a isso?\n> ");
    fgets(novo.resposta, MAX, stdin);
    novo.resposta[strcspn(novo.resposta, "\n")] = 0; // Remover \n
    inserir(head, novo);
    salvar_conhecimento(*head);
    printf("Obrigado! Agora aprendi algo novo.\n");
}

void mensagem_motivacional(const char *genero) {
    if (strcmp(genero, "feminino") == 0) {
        printf("\n[Psicóloga]: Você é incrível! Nunca esqueça da sua força interior.\n");
    } else {
        printf("\n[Psicólogo]: Você é forte e capaz! Acredite sempre em você.\n");
    }
}

int main() {
    Node *conhecimento = NULL;
    char genero[20];
    char entrada[MAX];
    char nome_usuario[50];

    carregar_conhecimento(&conhecimento);

    printf("Bem-vindo ao ChatBot Psicólogo!\n");
    printf("Antes de começarmos, por favor informe seu nome: ");
    fgets(nome_usuario, sizeof(nome_usuario), stdin);
    nome_usuario[strcspn(nome_usuario, "\n")] = 0;

    printf("Deseja conversar com um psicólogo (masculino) ou psicóloga (feminino)? ");
    fgets(genero, sizeof(genero), stdin);
    genero[strcspn(genero, "\n")] = 0;

    printf("\n[%s]: Olá %s! Estou aqui para te ouvir. Vamos conversar!\n", 
           strcmp(genero, "feminino") == 0 ? "Psicóloga" : "Psicólogo", 
           nome_usuario);

    while (1) {
        printf("\nVocê: ");
        fgets(entrada, MAX, stdin);
        entrada[strcspn(entrada, "\n")] = 0;

        if (strcmp(entrada, "sair") == 0) {
            printf("\n[%s]: Foi ótimo conversar com você, %s! Até logo!\n", 
                   strcmp(genero, "feminino") == 0 ? "Psicóloga" : "Psicólogo", 
                   nome_usuario);
            break;
        }

        Node *resposta_encontrada = buscar_resposta(conhecimento, entrada);
        if (resposta_encontrada != NULL) {
            printf("\n[%s]: %s\n", 
                   strcmp(genero, "feminino") == 0 ? "Psicóloga" : "Psicólogo", 
                   resposta_encontrada->dado.resposta);
        } else {
            aprender_resposta(&conhecimento, entrada);
        }

        // Enviar uma mensagem motivacional aleatória
        mensagem_motivacional(genero);
    }

    // Liberar memória
    Node *temp;
    while (conhecimento != NULL) {
        temp = conhecimento;
        conhecimento = conhecimento->next;
        free(temp);
    }

    return 0;
}