#include <Arduino.h>
#if defined(ESP32)
#include <WiFi.h>
#elif defined(ESP8266)
#include <ESP8266WiFi.h>
#endif

#include "google-sheets.h"

// WiFi credentials
#define WIFI_SSID "YOUR_WIFI_SSID"
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"

// Google Sheets credentials - replace with your own
#define PROJECT_ID "YOUR_PROJECT_ID"
#define CLIENT_EMAIL "YOUR_CLIENT_EMAIL@your-project.iam.gserviceaccount.com"
const char PRIVATE_KEY[] PROGMEM = "-----BEGIN PRIVATE KEY-----\nYOUR_PRIVATE_KEY_HERE\n-----END PRIVATE KEY-----\n";

// Email to share the spreadsheet with
#define USER_EMAIL "YOUR_EMAIL@gmail.com"

GoogleSheetClient sheets;
String spreadsheetId = "";
bool operationComplete = false;

void setup() {
  Serial.begin(115200);
  Serial.println();
  Serial.println("Google Sheets: Create and Write Data Example");
  
  // Connect to WiFi
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to WiFi...");
  
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(300);
  }
  
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  
  // Initialize Google Sheets client
  if (sheets.begin(CLIENT_EMAIL, PROJECT_ID, PRIVATE_KEY)) {
    Serial.println("Google Sheets client initialized successfully!");
  } else {
    Serial.println("Failed to initialize Google Sheets client");
    while (1) delay(1000); // Halt if initialization fails
  }
}

void loop() {
  // Process Google Sheets client
  sheets.loop();
  
  // Check if client is ready and we haven't completed our operations
  if (sheets.ready() && !operationComplete) {
    // Step 1: Create a new spreadsheet
    createSpreadsheet();
    delay(2000); // Give a little time between operations
    
    // If we successfully created a spreadsheet and have its ID
    if (spreadsheetId.length() > 0) {
      // Step 2: Write data to the spreadsheet
      writeDataToSpreadsheet();
      
      operationComplete = true;
      Serial.println("\nAll operations completed successfully!");
      Serial.println("You can access your spreadsheet in Google Drive");
    }
  }
  
  // Just wait if operations are complete
  if (operationComplete) {
    delay(60000); // Check every minute
    Serial.println("Operations completed. Waiting...");
  }
}

void createSpreadsheet() {
  Serial.println("\n--- Creating a new spreadsheet ---");
  
  // Create a unique name using millis()
  String spreadsheetName = "ESP_Data_" + String(millis());
  
  String response = sheets.createSpreadsheet(
    spreadsheetName.c_str(),  // Title
    "Data",                   // Sheet name
    100,                      // Number of rows
    10,                       // Number of columns
    USER_EMAIL                // Email to share with
  );
  
  // Extract the spreadsheet ID from the response
  FirebaseJson json;
  json.setJsonData(response);
  
  FirebaseJsonData result;
  json.get(result, "spreadsheetId");
  
  if (result.success) {
    spreadsheetId = result.stringValue;
    Serial.println("Spreadsheet created successfully!");
    Serial.println("Spreadsheet ID: " + spreadsheetId);
    
    // Extract and display the spreadsheet URL
    FirebaseJsonData urlResult;
    json.get(urlResult, "spreadsheetUrl");
    if (urlResult.success) {
      Serial.println("Spreadsheet URL: " + urlResult.stringValue);
    }
  } else {
    Serial.println("Failed to create spreadsheet or extract ID. Response: " + response);
  }
}

void writeDataToSpreadsheet() {
  Serial.println("\n--- Writing data to the spreadsheet ---");
  
  // First, set up headers
  FirebaseJson headerRange;
  headerRange.add("range", "Data!A1:D1");
  headerRange.add("majorDimension", "ROWS");
  headerRange.set("values/[0]/[0]", "ID");
  headerRange.set("values/[0]/[1]", "Date");
  headerRange.set("values/[0]/[2]", "Value");
  headerRange.set("values/[0]/[3]", "Status");
  
  bool success = sheets.updateValues(spreadsheetId.c_str(), "Data!A1:D1", &headerRange);
  
  if (success) {
    Serial.println("Headers written successfully!");
  } else {
    Serial.println("Error writing headers: " + sheets.errorReason());
    return;
  }
  
  // Now add some sample data
  FirebaseJson dataRange;
  dataRange.add("range", "Data!A2:D4");
  dataRange.add("majorDimension", "ROWS");
  
  // Row 1 data
  dataRange.set("values/[0]/[0]", "1");
  dataRange.set("values/[0]/[1]", getFormattedDate());
  dataRange.set("values/[0]/[2]", "42.5");
  dataRange.set("values/[0]/[3]", "OK");
  
  // Row 2 data
  dataRange.set("values/[1]/[0]", "2");
  dataRange.set("values/[1]/[1]", getFormattedDate());
  dataRange.set("values/[1]/[2]", "36.8");
  dataRange.set("values/[1]/[3]", "Warning");
  
  // Row 3 data
  dataRange.set("values/[2]/[0]", "3");
  dataRange.set("values/[2]/[1]", getFormattedDate());
  dataRange.set("values/[2]/[2]", "52.1");
  dataRange.set("values/[2]/[3]", "Error");
  
  success = sheets.updateValues(spreadsheetId.c_str(), "Data!A2:D4", &dataRange);
  
  if (success) {
    Serial.println("Data written successfully!");
  } else {
    Serial.println("Error writing data: " + sheets.errorReason());
  }
}

// Helper function to get a formatted date string
String getFormattedDate() {
  // In a real application, you would use NTP to get real time
  // For this example, we'll just create a timestamp with millis()
  unsigned long ms = millis();
  int seconds = ms / 1000;
  int minutes = seconds / 60;
  int hours = minutes / 60;
  
  return String("2023-03-") + random(10, 31) + " " + 
         String(hours % 24) + ":" + String(minutes % 60) + ":" + String(seconds % 60);
}