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

#define MAX 100

typedef struct {
    int id;
    char nome[100];
    char telefone[20];
    char email[100];
    char referencia[100];
} Pessoa;

typedef struct Node {
    Pessoa pessoa;
    struct Node *next;
} Node;

// Funções de Manipulação
Node* criar_node(Pessoa p) {
    Node *novo = (Node*)malloc(sizeof(Node));
    if (novo) {
        novo->pessoa = p;
        novo->next = NULL;
    }
    return novo;
}

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

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

void carregar_pessoas(Node **head) {
    FILE *fp = fopen("pessoas.dat", "rb");
    if (!fp) return; // Se não existir, não carrega nada

    Pessoa p;
    while (fread(&p, sizeof(Pessoa), 1, fp)) {
        inserir(head, p);
    }
    fclose(fp);
}

void exibir_pessoa(Pessoa p) {
    printf("ID: %d\n", p.id);
    printf("Nome: %s\n", p.nome);
    printf("Telefone: %s\n", p.telefone);
    printf("Email: %s\n", p.email);
    printf("Referencia: %s\n", p.referencia);
    printf("---------------------------------\n");
}

void listar_pessoas(Node *head) {
    Node *temp = head;
    while (temp != NULL) {
        exibir_pessoa(temp->pessoa);
        temp = temp->next;
    }
}

void buscar_pessoas(Node *head, const char *query) {
    Node *temp = head;
    int encontrados = 0;
    while (temp != NULL) {
        if (strcasestr(temp->pessoa.nome, query) != NULL) {
            exibir_pessoa(temp->pessoa);
            encontrados++;
        }
        temp = temp->next;
    }
    if (encontrados == 0)
        printf("Nenhum registro encontrado.\n");
}

// Função de cadastro de nova pessoa
void cadastrar_pessoa(Node **head) {
    Pessoa p;
    printf("Digite o ID: ");
    scanf("%d", &p.id);
    getchar(); // limpar \n

    printf("Digite o Nome completo: ");
    fgets(p.nome, sizeof(p.nome), stdin);
    p.nome[strcspn(p.nome, "\n")] = 0; // remover \n

    printf("Digite o Telefone: ");
    fgets(p.telefone, sizeof(p.telefone), stdin);
    p.telefone[strcspn(p.telefone, "\n")] = 0;

    printf("Digite o Email: ");
    fgets(p.email, sizeof(p.email), stdin);
    p.email[strcspn(p.email, "\n")] = 0;

    printf("Digite a Referência: ");
    fgets(p.referencia, sizeof(p.referencia), stdin);
    p.referencia[strcspn(p.referencia, "\n")] = 0;

    inserir(head, p);
    salvar_pessoas(*head);
    printf("Cadastro realizado com sucesso!\n");
}

// Menu Principal
int main() {
    Node *head = NULL;
    int opcao;
    char busca[MAX];

    carregar_pessoas(&head);

    do {
        printf("\n=== SISTEMA DE CADASTRO ===\n");
        printf("1 - Cadastrar Pessoa\n");
        printf("2 - Listar Pessoas\n");
        printf("3 - Buscar Pessoa por Nome\n");
        printf("4 - Sair\n");
        printf("Escolha uma opção: ");
        scanf("%d", &opcao);
        getchar(); // limpar \n

        switch(opcao) {
            case 1:
                cadastrar_pessoa(&head);
                break;
            case 2:
                listar_pessoas(head);
                break;
            case 3:
                printf("Digite o nome ou parte do nome para buscar: ");
                fgets(busca, sizeof(busca), stdin);
                busca[strcspn(busca, "\n")] = 0;
                buscar_pessoas(head, busca);
                break;
            case 4:
                printf("Encerrando...\n");
                break;
            default:
                printf("Opção inválida!\n");
        }
    } while (opcao != 4);

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

    return 0;
}