<?php

// --- Database Configuration ---
$host = "localhost";
$dbName = "accurate_be"; // Make sure this is the correct database name
$userName = "accurate_be";
$pass = "Saiful.1633";

// Start the session *before* any output
if (session_status() == PHP_SESSION_NONE) {
    session_start();
}

header('Content-Type: application/json'); // Set content type to JSON

$conn = null;

try {
    $conn = new PDO("mysql:host=$host;dbname=$dbName", $userName, $pass);
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // Fetch rows as associative arrays by default
} catch (PDOException $e) {
    error_log("Database connection error: " . $e->getMessage());
    // Only show generic error to client in production
    echo json_encode(['success' => false, 'message' => 'Database connection failed.']);
    exit; // Stop script execution on DB error
}

// --- Helper function to get image Base64 from URL or data string ---
function getImageBase64($imageData, $sourceType = 'none') {
    if (empty($imageData) || $sourceType === 'none') {
        return null;
    }

    $imageData = trim($imageData);
    if (empty($imageData)) return null;

    if ($sourceType === 'file') {
        if (preg_match('/^data:image\/(.*?);base64,(.*)$/', $imageData, $matches)) {
            return $matches[2]; // Return the pure Base64 string
        }
        error_log("getImageBase64: Data for source 'file' is not a valid Data URL format.");
        return null;

    } elseif ($sourceType === 'url') {
        if (filter_var($imageData, FILTER_VALIDATE_URL)) {
            $response = false;
            if (function_exists('curl_init')) {
                $ch = curl_init();
                curl_setopt($ch, CURLOPT_URL, $imageData);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
                curl_setopt($ch, CURLOPT_TIMEOUT, 10);
                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // Dev only, disable in prod
                curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // Dev only, disable in prod
                curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; AdminDashboard/1.0)'); // Good practice
                $response = curl_exec($ch);
                $http_status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
                $curl_error = curl_error($ch);
                curl_close($ch);

                if ($response === FALSE || $http_status !== 200) {
                    error_log("Failed to fetch image from URL (cURL error: {$curl_error}, Status: {$http_status}): " . $imageData);
                    return null;
                }

            } elseif (ini_get('allow_url_fopen')) {
                 error_log("cURL not available. Using file_get_contents for URL fetch.");
                 $context = stream_context_create(['http' => ['timeout' => 10, 'ignore_errors' => true]]);
                 $response = @file_get_contents($imageData, false, $context); // @ suppresses warnings

                 if ($response === FALSE) {
                      error_log("Failed to fetch image from URL (file_get_contents error): " . $imageData);
                      return null;
                 }
                  // Check HTTP headers from file_get_contents response
                  $http_response_header = $http_response_header ?? [];
                   $is_success = false;
                    foreach($http_response_header as $header) {
                        if (preg_match('/^HTTP\/[\d\.]+\s+200\s+OK/i', $header)) {
                            $is_success = true;
                            break;
                        }
                    }
                    if (!$is_success) {
                        error_log("Failed to fetch image from URL (bad HTTP status): " . $imageData);
                        return null;
                    }
            } else {
                 error_log("getImageBase64: Neither cURL nor allow_url_fopen are enabled. Cannot fetch image from URL.");
                 return null; // Cannot fetch URL
            }


            // If we have response content, encode it
            if ($response !== false) {
                 return base64_encode($response);
            }

        }
        error_log("getImageBase64: Invalid URL format provided for source 'url': " . $imageData);
        return null;

    }

     // Fallback for potentially old raw base64 data in DB (less reliable without sourceType)
     if (!empty($imageData) && preg_match('/^[a-zA-Z0-9\/+=]+$/', $imageData)) {
          return $imageData; // Looks like base64, return it
     }

     if (!empty($imageData)) {
          error_log("getImageBase64: Data exists but source type is unknown or data format is unexpected.");
     }

    return null;
}

// --- Helper function to check for duplicate product name or barcode ---
function checkExistingProduct($conn, $productName, $barcode) {
    $isDuplicateName = false;
    $isDuplicateBarcode = false;

    $productName = trim($productName);
    $barcode = trim($barcode);

    // Check for duplicate name if provided
    if (!empty($productName)) {
        $stmt = $conn->prepare("SELECT COUNT(*) FROM Products WHERE ProductName = :name");
        $stmt->bindParam(':name', $productName, PDO::PARAM_STR);
        $stmt->execute();
        if ($stmt->fetchColumn() > 0) {
            $isDuplicateName = true;
        }
    }

    // Check for duplicate barcode if provided and not empty
    if (!empty($barcode)) {
        $stmt = $conn->prepare("SELECT COUNT(*) FROM Products WHERE Barcode = :barcode AND Barcode IS NOT NULL AND Barcode != ''");
        $stmt->bindParam(':barcode', $barcode, PDO::PARAM_STR);
        $stmt->execute();
        if ($stmt->fetchColumn() > 0) {
            $isDuplicateBarcode = true;
        }
    }

    return ['isDuplicateName' => $isDuplicateName, 'isDuplicateBarcode' => $isDuplicateBarcode];
}

// --- Authentication Check ---
// Actions that require login: fetch_requests, fetch_request_by_id, approve_request, add_product, delete_request, check_duplicate, logout
// Actions that do NOT require login: login, check_auth

$action = $_POST['action'] ?? null; // Get action safely

$public_actions = ['login', 'check_auth']; // Actions accessible without login

// Check if the action requires authentication and if the user is NOT logged in
if (!in_array($action, $public_actions) && (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true)) {
    echo json_encode(['success' => false, 'message' => 'Authentication required. Please log in.']);
    exit; // Stop script if not logged in and action is protected
}


// --- API Actions ---

if ($action) { // Only process if an action was provided
    switch ($action) {
        case 'login':
            $username = $_POST['username'] ?? '';
            $password = $_POST['password'] ?? '';

            if (empty($username) || empty($password)) {
                 echo json_encode(['success' => false, 'message' => 'Username and password are required.']);
                 exit;
            }

            try {
                // Fetch admin credentials from MetaData table
                $stmt = $conn->query("SELECT meta_key, meta_value FROM MetaData WHERE meta_key IN ('AdminUsername', 'AdminPass')");
                $metadata = $stmt->fetchAll(PDO::FETCH_KEY_PAIR); // Fetches as ['meta_key' => 'meta_value']

                $storedUsername = $metadata['AdminUsername'] ?? null;
                $storedHash = $metadata['AdminPass'] ?? null;

                // Verify credentials
                if ($storedUsername && $storedHash && $username === $storedUsername && password_verify($password, $storedHash)) {
                    // Login successful
                    $_SESSION['loggedin'] = true;
                    $_SESSION['username'] = $username; // Store username in session

                    echo json_encode(['success' => true, 'message' => 'Login successful.']);
                } else {
                    // Login failed
                    // Use generic message for security
                    echo json_encode(['success' => false, 'message' => 'Invalid username or password.']);
                }

            } catch (PDOException $e) {
                error_log("Database error during login: " . $e->getMessage());
                echo json_encode(['success' => false, 'message' => 'Error during login process.']);
            }
            break;

        case 'logout':
             // This action is protected by the auth check above
             session_unset(); // Unset all session variables
             session_destroy(); // Destroy the session

             echo json_encode(['success' => true, 'message' => 'Logged out successfully.']);
            break;

        case 'check_auth':
             // This action is public, it just tells the frontend if they are logged in
             if (isset($_SESSION['loggedin']) && $_SESSION['loggedin'] === true) {
                  echo json_encode(['success' => true, 'message' => 'Authenticated.']);
             } else {
                  echo json_encode(['success' => false, 'message' => 'Not authenticated.']);
             }
            break;


        case 'fetch_requests':
            // This action is protected by the auth check above
            try {
                $stmt = $conn->query("SELECT id, product_name, product_image_url, product_brand, product_category, sub_category, barcode FROM Products_Req ORDER BY id DESC");
                $requests = $stmt->fetchAll();

                echo json_encode(['success' => true, 'requests' => $requests]);
            } catch (PDOException $e) {
                 error_log("Error fetching requests: " . $e->getMessage());
                echo json_encode(['success' => false, 'message' => 'Error fetching requests.']);
            }
            break;

        case 'fetch_request_by_id':
             // This action is protected by the auth check above
             if (!isset($_POST['id']) || empty($_POST['id'])) {
                echo json_encode(['success' => false, 'message' => 'Request ID not provided.']);
                exit;
             }
             $id = $_POST['id'];

            try {
                $stmt = $conn->prepare("SELECT * FROM Products_Req WHERE id = :id LIMIT 1");
                $stmt->bindParam(':id', $id, PDO::PARAM_INT);
                $stmt->execute();
                $request = $stmt->fetch();

                if ($request) {
                    echo json_encode(['success' => true, 'request' => $request]);
                } else {
                    echo json_encode(['success' => false, 'message' => 'Request not found.']);
                }
            } catch (PDOException $e) {
                 error_log("Error fetching request details (ID: {$id}): " . $e->getMessage());
                echo json_encode(['success' => false, 'message' => 'Error fetching request details.']);
            }
            break;

        case 'approve_request':
            // This action is protected by the auth check above
            if (!isset($_POST['id']) || empty($_POST['id'])) {
                echo json_encode(['success' => false, 'message' => "Request ID missing."]);
                exit;
            }
             if (!isset($_POST['ProductName']) || empty(trim($_POST['ProductName'] ?? ''))) {
                echo json_encode(['success' => false, 'message' => "Product Name is required for approval."]);
                exit;
             }

            $requestId = $_POST['id'];
            $productName = trim($_POST['ProductName'] ?? '');
            $barcode = trim($_POST['Barcode'] ?? '');


            try {
                $conn->beginTransaction();

                 // --- FINAL DUPLICATE CHECK BEFORE INSERTION ---
                 $duplicates = checkExistingProduct($conn, $productName, $barcode);
                 $duplicateMessages = [];
                 if ($duplicates['isDuplicateName']) {
                     $duplicateMessages[] = "Product Name '{$productName}' already exists.";
                 }
                 // Only check barcode duplicate if a barcode was provided in the form
                 if (!empty($barcode) && $duplicates['isDuplicateBarcode']) {
                      $duplicateMessages[] = "Barcode '{$barcode}' already exists.";
                 }

                 if (!empty($duplicateMessages)) {
                     $conn->rollBack(); // Rollback transaction as we won't insert
                     echo json_encode(['success' => false, 'message' => "Could not approve: " . implode(" ", $duplicateMessages)]);
                     exit;
                 }
                 // --- END FINAL DUPLICATE CHECK ---


                // Prepare data for insertion into Products using POSTed values
                $productData = [
                    'ProductName' => $productName,
                    'ProductImage' => null, // Processed below
                    'ProductBrand' => trim($_POST['ProductBrand'] ?? ''),
                    'ProductCategory' => trim($_POST['ProductCategory'] ?? ''),
                    'SubCategory' => trim($_POST['SubCategory'] ?? ''),
                    'Barcode' => $barcode,
                    'MoreInfo' => trim($_POST['MoreInfo'] ?? ''),
                    'AlternativeImage1' => null, // Processed below
                    'AlternativeName1' => trim($_POST['AlternativeName1'] ?? ''),
                    'AlternativeBrand1' => trim($_POST['AlternativeBrand1'] ?? ''),
                    'AlternativeBarcode1' => trim($_POST['AlternativeBarcode1'] ?? ''),
                    'AlternativeImage2' => null, // Processed below
                    'AlternativeName2' => trim($_POST['AlternativeName2'] ?? ''),
                    'AlternativeBrand2' => trim($_POST['AlternativeBrand2'] ?? ''),
                    'AlternativeBarcode2' => trim($_POST['AlternativeBarcode2'] ?? ''),
                    'AlternativeImage3' => null, // Processed below
                    'AlternativeName3' => trim($_POST['AlternativeName3'] ?? ''),
                    'AlternativeBrand3' => trim($_POST['AlternativeBrand3'] ?? ''),
                    'AlternativeBarcode3' => trim($_POST['AlternativeBarcode3'] ?? ''),
                ];

                // --- Process Main Product Image ---
                $mainImageData = $_POST['ProductImage'] ?? null;
                $mainImageSource = $_POST['ProductImageSource'] ?? 'none';
                 if (!empty($mainImageData) && $mainImageSource !== 'none') {
                    $base64MainImage = getImageBase64($mainImageData, $mainImageSource);
                     if ($base64MainImage === null) {
                         // Log error in getImageBase64, return user-friendly message
                         $conn->rollBack();
                         $errorMsg = ($mainImageSource === 'url') ?
                                     "Failed to fetch or process main product image from URL. Please check the URL or try uploading a file." :
                                     "Failed to process main product image file.";
                         echo json_encode(['success' => false, 'message' => $errorMsg]);
                         exit;
                    }
                    $productData['ProductImage'] = $base64MainImage;
                 }


                // --- Process Alternative Images ---
                for($i = 1; $i <= 3; $i++) {
                    $imageFieldName = "AlternativeImage{$i}";
                    $imageSourceFieldName = "AlternativeImageSource{$i}";

                    $imageData = $_POST[$imageFieldName] ?? null;
                    $imageSource = $_POST[$imageSourceFieldName] ?? 'none';

                    if (!empty($imageData) && $imageSource !== 'none') {
                        $base64Image = getImageBase64($imageData, $imageSource);
                        if ($base64Image === null) {
                             $conn->rollBack();
                              $errorMsg = ($imageSource === 'url') ?
                                          "Failed to fetch or process image for Alternative {$i} from URL. Please check the URL or try uploading a file." :
                                          "Failed to process image file for Alternative {$i}.";
                             echo json_encode(['success' => false, 'message' => $errorMsg]);
                             exit;
                        }
                         $productData[$imageFieldName] = $base64Image;
                    } else {
                         $productData[$imageFieldName] = null;
                    }
                }


                // 3. Insert into Products table
                 $columns = implode(', ', array_keys($productData));
                 $placeholders = implode(', ', array_fill(0, count($productData), '?'));
                $insertSql = "INSERT INTO Products ($columns) VALUES ($placeholders)";
                $stmt = $conn->prepare($insertSql);

                 $values = array_values($productData);

                $stmt->execute($values);

                // 4. Delete from Products_Req table
                $deleteSql = "DELETE FROM Products_Req WHERE id = :id";
                $stmt = $conn->prepare($deleteSql);
                $stmt->bindParam(':id', $requestId, PDO::PARAM_INT);
                $stmt->execute();

                $conn->commit();

                echo json_encode(['success' => true, 'message' => 'Product request approved and added to products successfully.']);

            } catch (PDOException $e) {
                 $conn->rollBack();
                 error_log("Database error during approval (Req ID: {$requestId}): " . $e->getMessage());
                echo json_encode(['success' => false, 'message' => 'Database error during approval.']);
            } catch (Exception $e) {
                 $conn->rollBack();
                 error_log("General error during approval (Req ID: {$requestId}): " . $e->getMessage());
                 echo json_encode(['success' => false, 'message' => 'An unexpected error occurred during approval.']);
            }
            break;

        case 'add_product': // Action for direct adding
             // This action is protected by the auth check above
             if (!isset($_POST['ProductName']) || empty(trim($_POST['ProductName'] ?? ''))) {
                echo json_encode(['success' => false, 'message' => "Product Name is required."]);
                exit;
             }

             $productName = trim($_POST['ProductName'] ?? '');
             $barcode = trim($_POST['Barcode'] ?? '');


             try {
                 // --- FINAL DUPLICATE CHECK BEFORE INSERTION ---
                 $duplicates = checkExistingProduct($conn, $productName, $barcode);
                 $duplicateMessages = [];
                 if ($duplicates['isDuplicateName']) {
                     $duplicateMessages[] = "Product Name '{$productName}' already exists.";
                 }
                  // Only check barcode duplicate if a barcode was provided in the form
                 if (!empty($barcode) && $duplicates['isDuplicateBarcode']) {
                      $duplicateMessages[] = "Barcode '{$barcode}' already exists.";
                 }


                 if (!empty($duplicateMessages)) {
                     echo json_encode(['success' => false, 'message' => "Could not add product: " . implode(" ", $duplicateMessages)]);
                     exit;
                 }
                 // --- END FINAL DUPLICATE CHECK ---

                // Prepare data for insertion into Products using POSTed values
                $productData = [
                    'ProductName' => $productName,
                    'ProductImage' => null, // Processed below
                    'ProductBrand' => trim($_POST['ProductBrand'] ?? ''),
                    'ProductCategory' => trim($_POST['ProductCategory'] ?? ''),
                    'SubCategory' => trim($_POST['SubCategory'] ?? ''),
                    'Barcode' => $barcode,
                    'MoreInfo' => trim($_POST['MoreInfo'] ?? ''),
                    'AlternativeImage1' => null, // Processed below
                    'AlternativeName1' => trim($_POST['AlternativeName1'] ?? ''),
                    'AlternativeBrand1' => trim($_POST['AlternativeBrand1'] ?? ''),
                    'AlternativeBarcode1' => trim($_POST['AlternativeBarcode1'] ?? ''),
                    'AlternativeImage2' => null, // Processed below
                    'AlternativeName2' => trim($_POST['AlternativeName2'] ?? ''),
                    'AlternativeBrand2' => trim($_POST['AlternativeBrand2'] ?? ''),
                    'AlternativeBarcode2' => trim($_POST['AlternativeBarcode2'] ?? ''),
                    'AlternativeImage3' => null, // Processed below
                    'AlternativeName3' => trim($_POST['AlternativeName3'] ?? ''),
                    'AlternativeBrand3' => trim($_POST['AlternativeBrand3'] ?? ''),
                    'AlternativeBarcode3' => trim($_POST['AlternativeBarcode3'] ?? ''),
                ];

                 // --- Process Main Product Image ---
                 $mainImageData = $_POST['ProductImage'] ?? null;
                 $mainImageSource = $_POST['ProductImageSource'] ?? 'none';
                  if (!empty($mainImageData) && $mainImageSource !== 'none') {
                     $base64MainImage = getImageBase64($mainImageData, $mainImageSource);
                      if ($base64MainImage === null) {
                          $errorMsg = ($mainImageSource === 'url') ?
                                      "Failed to fetch or process main product image from URL. Please check the URL or try uploading a file." :
                                      "Failed to process main product image file.";
                          echo json_encode(['success' => false, 'message' => $errorMsg]);
                          exit;
                     }
                     $productData['ProductImage'] = $base64MainImage;
                  }


                 // --- Process Alternative Images ---
                 for($i = 1; $i <= 3; $i++) {
                     $imageFieldName = "AlternativeImage{$i}";
                     $imageSourceFieldName = "AlternativeImageSource{$i}";

                     $imageData = $_POST[$imageFieldName] ?? null;
                     $imageSource = $_POST[$imageSourceFieldName] ?? 'none';

                     if (!empty($imageData) && $imageSource !== 'none') {
                         $base64Image = getImageBase64($imageData, $imageSource);
                         if ($base64Image === null) {
                              $errorMsg = ($imageSource === 'url') ?
                                           "Failed to fetch or process image for Alternative {$i} from URL. Please check the URL or try uploading a file." :
                                           "Failed to process image file for Alternative {$i}.";
                              echo json_encode(['success' => false, 'message' => $errorMsg]);
                              exit;
                         }
                          $productData[$imageFieldName] = $base64Image;
                     } else {
                          $productData[$imageFieldName] = null;
                     }
                 }

                 // Insert into Products table
                 $columns = implode(', ', array_keys($productData));
                 $placeholders = implode(', ', array_fill(0, count($productData), '?'));
                 $insertSql = "INSERT INTO Products ($columns) VALUES ($placeholders)";
                 $stmt = $conn->prepare($insertSql);

                 $values = array_values($productData);

                 $stmt->execute($values);

                 echo json_encode(['success' => true, 'message' => 'Product added successfully to the Products table.']);

             } catch (PDOException $e) {
                  error_log("Database error during direct product add: " . $e->getMessage());
                 echo json_encode(['success' => false, 'message' => 'Database error adding product.']);
             } catch (Exception $e) {
                 error_log("General error during direct product add: " . $e->getMessage());
                 echo json_encode(['success' => false, 'message' => 'An unexpected error occurred while adding the product.']);
             }

            break;

        case 'delete_request': // Used for both card delete and modal reject
             // This action is protected by the auth check above
             if (!isset($_POST['id']) || empty($_POST['id'])) {
                echo json_encode(['success' => false, 'message' => 'Request ID not provided for deletion.']);
                exit;
             }
             $id = $_POST['id'];

             try {
                 $stmt = $conn->prepare("DELETE FROM Products_Req WHERE id = :id");
                 $stmt->bindParam(':id', $id, PDO::PARAM_INT);
                 $stmt->execute();

                 if ($stmt->rowCount() > 0) {
                      echo json_encode(['success' => true, 'message' => 'Request deleted successfully.']);
                 } else {
                      echo json_encode(['success' => false, 'message' => 'Request not found or already processed.']);
                 }

             } catch (PDOException $e) {
                 error_log("Error deleting request (ID: {$id}): " . $e->getMessage());
                 echo json_encode(['success' => false, 'message' => 'Database error during deletion.']);
             }
            break;

        case 'check_duplicate': // Action for live duplicate checking
             // This action is protected by the auth check above
             $productName = trim($_POST['ProductName'] ?? '');
             $barcode = trim($_POST['Barcode'] ?? '');

             // At least one field must be provided to check
             if (empty($productName) && empty($barcode)) {
                  echo json_encode(['success' => false, 'message' => 'No data provided for duplicate check.']);
                  exit;
             }

             try {
                 $duplicates = checkExistingProduct($conn, $productName, $barcode);
                 echo json_encode(['success' => true, 'isDuplicateName' => $duplicates['isDuplicateName'], 'isDuplicateBarcode' => $duplicates['isDuplicateBarcode']]);

             } catch (PDOException $e) {
                 error_log("Database error during duplicate check: " . $e->getMessage());
                 echo json_encode(['success' => false, 'message' => 'Database error during duplicate check.']);
             }
            break;


        default:
            // This action is protected by the auth check above (if it's not a public action)
            echo json_encode(['success' => false, 'message' => 'Invalid action specified.']);
            break;
    }
} else {
    // No action specified in POST. Could be a direct GET request or malformed POST.
    // If not logged in, the auth check above will handle it.
    // If logged in, maybe return a default success or info message?
    // Or just let the frontend handle the initial load.
     if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
         // This case is already handled by the auth check at the top,
         // which would have exited with an error message.
     } else {
          // Logged in, but no action specified - maybe return success?
          // This case is unlikely with the frontend's behavior.
          // echo json_encode(['success' => true, 'message' => 'API endpoint reached.']);
     }
     // If no action is provided and not logged in, the script will have already exited.
     // If no action is provided and logged in, we should probably not do anything and let the frontend determine what to load.
}


// Close connection (optional)
$conn = null;

?>