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

#define MAX_SEATS 30
#define MAX_MOVIES 4
#define MAX_BOOKING 4
#define rows 5
#define cols 6

//Ticket
struct Ticket {
 char customerName[100];
 int booked;
};

//Movie
struct Movie {
 char movieName[50];
 struct Ticket seats[MAX_SEATS];
};
struct Movie movies[MAX_MOVIES] = {{"CPE Adventure"},{"Mufasa: The Lion King"},{"Ratatouille"},{"Avengers: Endgame"}};

//Movie list
void displayMovies(struct Movie movies[]) {
 printf("\n-- Movies list --\n");
 for (int i = 0; i < MAX_MOVIES; i++) {
  printf("\n%d. %s\n", i + 1, movies[i].movieName);
 }
}

// Seat booking
void bookTicket(struct Movie *movie) {
 int col;
 int numtickets;
 char name[50];
 char rowchar;

 //Display seat
 for (int row = 0; row < rows; row++) {
  for (int col = 0; col < cols; col++) {
   int seatIndex = row * cols + col;
   if (seatIndex >= MAX_SEATS) break;

   char rowChar = 'A' + row;
   printf("%c%d(", rowChar, col + 1);
   if (movie->seats[seatIndex].booked) printf("XX");
   else printf("");
   printf(")\t");
  }
  printf("\n\n");
 }

 printf("How many tickets do you want : ");
 scanf("%d", &numtickets);

 if (numtickets < 1 || numtickets > MAX_SEATS) {
  printf("Invalid number of seats!\n");
  return;
 }

 printf("Enter your name : ");
 scanf(" %[^\n]", name);  //C B8B#C B8B1C B8C B8C B9C B8B2C B8C B8B7C B9C B8

 for (int i = 0; i < numtickets; i++) {
  printf("\nBooking seat %d \n", i + 1);

  printf("Enter seat (Ex:A1): ");
  scanf(" %c%d", &rowchar, &col);
  rowchar = toupper(rowchar);

  int row = rowchar - 'A';
  if (row < 0 || row >= rows || col < 1 || col > cols) {
   printf("\nInvalid seat!\n");
   continue;
  }

  int seatIndex = row * cols + (col - 1);
  if (movie->seats[seatIndex].booked) {
   printf("\nSeat %c%d already booked!\n", rowchar, col);
   continue;
  }

  movie->seats[seatIndex].booked = 1;
  strcpy(movie->seats[seatIndex].customerName, name);

  printf("Seat %c%d reserved for %s\n", rowchar, col, name);
 }
}

//Cancel booking
void cancelBooking(struct Movie *movie) {
 int col;
 int numtickets;
 char name[50];
 char rowchar;

 //Display seat
 for (int row = 0; row < rows; row++) {
  for (int col = 0; col < cols; col++) {
   int seatIndex = row * cols + col;
   if (seatIndex >= MAX_SEATS) {
    break;
   }

   char rowChar = 'A' + row;  // C B9C B8C B8B%C B8C B9C B8B%C B8C B9C B8C B8B'C B9C B8C B9C B8C B8C B8B1C B8B'C B8 C B8B1C B8C B8B)C B8B# A, B, C, ...

   printf("%c%d(", rowChar, col + 1);

   if (movie->seats[seatIndex].booked) {
    printf("XX");
   }
   else {
    printf("");
   }
   printf(")\t");
  }
  printf("\n\n"); // C B8C B8B6C B9C B8C B8C B8B#C B8B#C B8C B8B1C B8C B9C B8B+C B8B!C B9C B9C B8B!C B8B7C B9C B8 C B8C B8 1 C B9C B8C B8B'
 }

 printf("\nPlease enter seat number to cancel (Ex : A1): \n");
 scanf(" %c%d", &rowchar, &col);
 rowchar = toupper(rowchar);


 int row = rowchar - 'A';
 if (row < 0 || row >= rows || col < 1 || col > cols) {
  printf("Invalid seat!\n");
  return;
 }

 int seatIndex = row * cols + (col - 1);
 if (movie->seats[seatIndex].booked == 0) {
  printf("Seat is available!\n");
  return;
 }
 else {
  movie->seats[seatIndex].booked = 0;
  strcpy(movie->seats[seatIndex].customerName, ""); // C B8B%C B8C B8C B8B7C B9C B8 C B8B%C B8B9C B8C B8C B9C B8B2
  printf("Seat %c%d successfully cancel\n", rowchar, col);
 }
}

//Seat available
void checkSeatStatus(struct Movie *movie) {
 printf("\nCheck seat available (%s)\n\n", movie->movieName);

 //Display seat
 for (int row = 0; row < rows; row++) {
  for (int col = 0; col < cols; col++) {
   int seatIndex = row * cols + col;
   if (seatIndex >= MAX_SEATS) {
    break;
   }

   char rowChar = 'A' + row;  // C B9C B8C B8B%C B8C B9C B8B%C B8C B9C B8C B8B'C B9C B8C B9C B8C B8C B8B1C B8B'C B8 C B8B1C B8C B8B)C B8B# A, B, C, ...

   printf("%c%d(", rowChar, col + 1);

   if (movie->seats[seatIndex].booked) {
    printf("XX");
   }
   else {
    printf("");
   }
   printf(")\t");
  }
  printf("\n\n"); // C B8C B8B6C B9C B8C B8C B8B#C B8B#C B8C B8B1C B8C B9C B8B+C B8B!C B9C B9C B8B!C B8B7C B9C B8 C B8C B8 1 C B9C B8C B8B'
 }
}

// Search bookings
void searchBooking(struct Movie movies[]) {
 int found = 0;
 char searchName[100];

 printf("Enter customer name to search : ");
 scanf(" %[^\n]", searchName);

 printf("\n--- Bookings for | %s | ---\n", searchName);

 for (int i = 0; i < MAX_MOVIES; i++) {
  for (int j = 0; j < MAX_SEATS; j++) {
   if (movies[i].seats[j].booked && strcmp(movies[i].seats[j].customerName, searchName) == 0) {

    int row = j / cols;
    int col = j % cols;

    printf("\n------------------------------\n");
    printf("\nMovie: %s \n", movies[i].movieName);
    printf("Seat: %c%d\n ", 'A' + row, col + 1);
    printf("\n------------------------------\n");
    found = 1;
   }
  }
 }
 if (!found) {
  printf("No bookings found for | %s |.\n", searchName);
 }
}

//Save data
void saveData(struct Movie movies[]) {
 FILE *file = fopen("ticketfinal.txt", "w");//C B9C B8C B8C B9C B8C B9C B8C B8B%C B9C B8C B8B7C B9C B8 ticketfinal.txt
 if (file == NULL) {
  printf("Error opening file for writing!\n");
  return;
 }

 for (int i = 0; i < MAX_MOVIES; i++) {
  fprintf(file, "Movie: %s\n", movies[i].movieName);
  for (int j = 0; j < MAX_SEATS; j++) {
   if (movies[i].seats[j].booked) {
    fprintf(file, "Seat %d: Booked by %s\n", j + 1, movies[i].seats[j].customerName);
   }
   else {
    fprintf(file, "Seat %d: Free\n", j + 1);
   }
  }
  fprintf(file, "------------------------------------------------------\n");
 }//C B9C B8C B9C B8C B8C B8B1C B8B'C B8C B8B1C B9C B8C B8B#C B8B0C B8B+C B8B'C B9C B8B2C B8C B9C B8C B9C B8B%C B8B0C B9C B8B#C B8B7C B9C B8 C B8

 fclose(file);
 printf("Data saved successfully to ticketfinal.txt!\n");
}
// Load data
void loadData(struct Movie movies[]) {
 FILE *file = fopen("ticketfinal.txt", "r");
 if (file == NULL) {
  printf("");
  return;
 }

 char line[200];
 int movieIndex = -1;
 while (fgets(line, sizeof(line), file)) {
  if (strncmp(line, "Movie:", 6) == 0) {
   movieIndex++;
  }
  else if (strncmp(line, "Seat", 4) == 0 && movieIndex >= 0) {
   int seatNumber;
   char status[20];
   char name[100] = "";

   if (strstr(line, "Booked by")) {
    sscanf(line, "Seat %d: Booked by %s", &seatNumber, name);
    movies[movieIndex].seats[seatNumber - 1].booked = 1;
    strcpy(movies[movieIndex].seats[seatNumber - 1].customerName, name);
   }
   else {
    sscanf(line, "Seat %d: %s", &seatNumber, status);
    movies[movieIndex].seats[seatNumber - 1].booked = 0;
    strcpy(movies[movieIndex].seats[seatNumber - 1].customerName, "");
   }
  }
 }
 fclose(file);
}

int main() {
 int choice;
 int movieChoice;

 printf("Majoi movies ticket booking system\n");
 loadData(movies); //C B9C B8B+C B8B%C B8C B8C B9C B8 C B8B!C B8B9C B8B%C B8C B8B2C B8C B9C B8C B8B%C B9C B8C B8B5C B9C B8C B8B1C B8C B8C B8B6C B8C B9C B8B'C B9

 while (1) {
  printf("\n|  -- Main menu --  |\n|                   |\n| 1. Ticket booking |");
  printf("\n| 2. Seat available |\n| 3. Cancel booking |\n| 4. search booking |");
  printf("\n| 5. Exit           |\nSelect menu (1-4): ");
  scanf("%d", &choice);

  switch (choice) {
  case 1:
   displayMovies(movies);
   printf("\nSelect movie (1-%d): \n", MAX_MOVIES);
   scanf("%d", &movieChoice);
   if (movieChoice < 1 || movieChoice > MAX_MOVIES) {
    printf("\nSelection failed!\n");
   }
   else {
    bookTicket(&movies[movieChoice - 1]);
   }
   break;

  case 2:
   displayMovies(movies);
   printf("\nSelect movie (1-%d): \n", MAX_MOVIES);
   scanf("%d", &movieChoice);
   if (movieChoice < 1 || movieChoice > MAX_MOVIES) {
    printf("\nSelection failed!\n");
   }
   else {
    checkSeatStatus(&movies[movieChoice - 1]);
   }
   break;

  case 3:
   displayMovies(movies);
   printf("\nSelect movie (1-%d): \n", MAX_MOVIES);
   scanf("%d", &movieChoice);
   if (movieChoice < 1 || movieChoice > MAX_MOVIES) {
    printf("\nSelection failed!\n");
   }
   else {
    cancelBooking(&movies[movieChoice - 1]);
   }
   break;

  case 4:
   searchBooking(movies);
   break;

  case 5:
   saveData(movies);//C B9C B8C B8C B8C B9C B8 C B8B!C B8B9C B8B%
   printf("\nThank you Jubjub!\n");
   return 0;

  default:
   printf("\nPlease select menu again (1-4)\n");
  }
 }
}