<?php
declare(strict_types=1);

/**
 * Simple, robust upload interface for a DMS.
 * Requirements: PHP 8+, PDO MySQL, ext-fileinfo enabled.
 */

//// --- CONFIG --- ////
$app = [
  'app_name'        => 'DMS',
  'base_url'        => '.', // or '/public' if served from subdir
  'storage_dir'     => dirname(__DIR__) . '/storage',  // put storage OUTSIDE web root if possible
  'max_upload_mb'   => 50,                              // UI hint only
  'max_upload_bytes'=> 50 * 1024 * 1024,               // server-side limit
  'allowed_mimes'   => [
      'application/pdf',
      'image/png','image/jpeg','image/gif',
      'text/plain',
      'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
      'application/msword',
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      'application/vnd.ms-excel',
      'application/zip',
  ],
  // replace with real signed-in user id
  'current_user_id' => 1,
];
$DB_HOST = 'localhost';
$DB_NAME = 'lands';
$DB_USER = 'root';
$DB_PASS = '';
$DB_CHARSET = 'utf8mb4';

// DB connection (adjust)
$pdo = new PDO(
 "mysql:host=$DB_HOST;dbname=$DB_NAME;charset=$DB_CHARSET",
  $DB_USER,
 $DB_PASS,
  [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET sql_mode='STRICT_ALL_TABLES', time_zone = '+00:00'",
  ]
);

//// --- HELPERS --- ////
function h(?string $s): string {
  return htmlspecialchars($s ?? '', ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
}
function csrf_token(): string {
  if (session_status() !== PHP_SESSION_ACTIVE) session_start();
  $_SESSION['csrf'] = $_SESSION['csrf'] ?? bin2hex(random_bytes(32));
  return $_SESSION['csrf'];
}
function csrf_check(string $token): void {
  if (session_status() !== PHP_SESSION_ACTIVE) session_start();
  if (!isset($_SESSION['csrf']) || !hash_equals($_SESSION['csrf'], $token)) {
    http_response_code(403); exit('CSRF validation failed');
  }
}
function ensure_storage(string $dir): void {
  if (!is_dir($dir) && !mkdir($dir, 0775, true) && !is_dir($dir)) {
    throw new RuntimeException('Failed to create storage directory');
  }
}
function detect_mime(string $path): string {
  $f = new finfo(FILEINFO_MIME_TYPE);
  return $f->file($path) ?: 'application/octet-stream';
}
function safe_ext(string $filename): string {
  $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
  return preg_replace('/[^a-z0-9]+/', '', $ext);
}
function random_basename(int $len=24): string { return bin2hex(random_bytes(intval($len/2))); }
function format_bytes(int $bytes): string {
  $u=['B','KB','MB','GB','TB']; $i=0;
  while ($bytes>=1024 && $i<count($u)-1){$bytes/=1024;$i++;}
  return sprintf('%.1f %s', $bytes, $u[$i]);
}

//// --- HANDLE POST --- ////
$errors = [];
$okMsg  = null;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
  csrf_check($_POST['csrf'] ?? '');

  $title   = trim($_POST['title'] ?? '');
  $docType = trim($_POST['doc_type'] ?? '');
  $file    = $_FILES['file'] ?? null;

  // Basic validations
  if (!$file || ($file['error'] ?? UPLOAD_ERR_NO_FILE) !== UPLOAD_ERR_OK) {
    $errors[] = 'Please choose a file to upload.';
  } else {
    if ($file['size'] > $app['max_upload_bytes']) {
      $errors[] = 'File too large. Max '. $app['max_upload_mb'] .' MB.';
    }
    $mime = detect_mime($file['tmp_name']);
    if (!in_array($mime, $app['allowed_mimes'], true)) {
      $errors[] = 'File type not allowed: ' . h($mime);
    }
  }

  if (!$errors) {
    // Make dated subfolder: storage/YYYY/MM/DD
    ensure_storage($app['storage_dir']);
    $origName  = $file['name'];
    $ext       = safe_ext($origName);
    $basename  = random_basename();
    $relPath   = date('Y/m/d') . '/' . $basename . ($ext ? ".$ext" : '');
    $absPath   = rtrim($app['storage_dir'], '/') . '/' . $relPath;

    if (!is_dir(dirname($absPath))) mkdir(dirname($absPath), 0775, true);

    if (!move_uploaded_file($file['tmp_name'], $absPath)) {
      $errors[] = 'Failed to save file.';
    } else {
      // Insert DB row
      $stmt = $pdo->prepare("
        INSERT INTO documents
          (filename, filepath, title, doc_type, filesize, owner_user_id, current_version_id, status, created_by)
        VALUES
          (:filename, :filepath, :title, :doc_type, :filesize, :owner_user_id, NULL, 'active', :created_by)
      ");
      $stmt->execute([
        ':filename'      => $origName,
        ':filepath'      => $relPath, // store relative path
        ':title'         => $title !== '' ? $title : pathinfo($origName, PATHINFO_FILENAME),
        ':doc_type'      => $docType ?: null,
        ':filesize'      => (int)$file['size'],
        ':owner_user_id' => (int)$app['current_user_id'],
        ':created_by'    => (int)$app['current_user_id'],
      ]);

      $okMsg = 'Uploaded <strong>'.h($origName).'</strong> ('.format_bytes((int)$file['size']).') successfully.';
    }
  }
}
?>
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title><?=h($app['app_name'])?> · Upload Document</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <!-- Bootstrap (CDN for demo; pin/version for production) -->
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet">
  <style>
    body { padding: 24px; }
    .dropzone {
      border: 2px dashed #b8c2cc; border-radius: .5rem; padding: 24px;
      background: #f8fafc; text-align: center; transition: background .2s, border-color .2s;
    }
    .dropzone.dragover { background: #eef6ff; border-color: #6597ff; }
  </style>
</head>
<body>
  <div class="container" style="max-width: 900px;">
    <div class="d-flex justify-content-between align-items-center mb-3">
      <h1 class="h3 mb-0">Upload Document</h1>
      <a class="btn btn-outline-secondary" href="./index.php">Back to Documents</a>
    </div>

    <?php if ($okMsg): ?>
      <div class="alert alert-success" role="alert"><?= $okMsg ?></div>
    <?php endif; ?>

    <?php if ($errors): ?>
      <div class="alert alert-danger" role="alert">
        <ul class="mb-0">
          <?php foreach ($errors as $e): ?><li><?=h($e)?></li><?php endforeach; ?>
        </ul>
      </div>
    <?php endif; ?>

    <div class="card">
      <div class="card-body">
        <form method="post" enctype="multipart/form-data" id="uploadForm" class="row g-3">
          <input type="hidden" name="csrf" value="<?=h(csrf_token())?>">

          <div class="col-12">
            <label class="form-label">Title <span class="text-muted">(optional)</span></label>
            <input type="text" name="title" maxlength="512" class="form-control" placeholder="e.g., Survey Plan / Contract / Invoice">
          </div>

          <div class="col-md-6">
            <label class="form-label">Document Type <span class="text-muted">(optional)</span></label>
            <input type="text" name="doc_type" maxlength="120" class="form-control" placeholder="e.g., Survey, CofO, Contract">
          </div>

          <div class="col-md-6">
            <label class="form-label">Max size</label>
            <input type="text" class="form-control" value="<?= (int)$app['max_upload_mb'] ?> MB" disabled>
          </div>

          <div class="col-12">
            <div class="dropzone" id="dropzone">
              <p class="mb-1">Drag & drop a file here, or click to choose</p>
              <small class="text-muted">Allowed: PDF, images, DOC/DOCX, XLS/XLSX, ZIP, TXT</small>
              <input class="form-control mt-3" type="file" name="file" id="fileInput" required
                     accept=".pdf,.png,.jpg,.jpeg,.gif,.txt,.doc,.docx,.xls,.xlsx,.zip,application/pdf,image/*,.txt,.doc,.docx,.xls,.xlsx,.zip">
            </div>
          </div>

          <div class="col-12 d-flex gap-2">
            <button class="btn btn-success">Upload</button>
            <button type="reset" class="btn btn-outline-secondary">Reset</button>
          </div>
        </form>
      </div>
    </div>

    <div class="mt-3 text-muted" style="font-size:.9rem;">
      Tip: Files are stored in <code><?=h($app['storage_dir'])?></code> by date (YYYY/MM/DD). Make sure this folder is writable by PHP.
    </div>
  </div>

  <script>
    // Drag & drop UX (enhances the regular file input)
    const dz = document.getElementById('dropzone');
    const fi = document.getElementById('fileInput');

    ['dragenter','dragover'].forEach(eName => {
      dz.addEventListener(eName, e => { e.preventDefault(); e.stopPropagation(); dz.classList.add('dragover'); });
    });
    ['dragleave','drop'].forEach(eName => {
      dz.addEventListener(eName, e => { e.preventDefault(); e.stopPropagation(); dz.classList.remove('dragover'); });
    });
    dz.addEventListener('drop', e => {
      const files = e.dataTransfer.files;
      if (files && files.length) {
        fi.files = files; // put dropped file into the input
      }
    });
    dz.addEventListener('click', () => fi.click());
  </script>
</body>
</html>
