<?php
// app/models/Inspection.php
require_once __DIR__ . '/../config/config.php';
require_once __DIR__ . '/../config/db.php';
require_once __DIR__ . '/Notification.php';

class Inspection
{
  public static function listByUnit(int $unitId): array
  {
    $stmt = db()->prepare("
      SELECT
        i.*,
        u.unit_code,
        b.name AS building_name,
        usr.full_name AS staff_name
      FROM inspections i
      JOIN units u ON u.id = i.unit_id
      JOIN buildings b ON b.id = u.building_id
      LEFT JOIN users usr ON usr.id = i.staff_user_id
      WHERE i.unit_id = ?
      ORDER BY i.inspected_at DESC, i.id DESC
    ");
    $stmt->execute([$unitId]);
    return $stmt->fetchAll();
  }

  public static function photosByInspection(int $inspectionId): array
  {
    $stmt = db()->prepare("
      SELECT *
      FROM inspection_photos
      WHERE inspection_id = ?
      ORDER BY uploaded_at ASC, id ASC
    ");
    $stmt->execute([$inspectionId]);
    return $stmt->fetchAll();
  }

  public static function create(
    int $unitId,
    int $staffUserId,
    string $notes,
    array $beforeFiles,
    array $afterFiles,
    ?float $geoLat = null,
    ?float $geoLng = null,
    ?int $geoAccuracy = null,
    ?string $geoAddress = null
  ): int {
    db()->beginTransaction();

    try {
      $stmt = db()->prepare("
        INSERT INTO inspections (unit_id, staff_user_id, inspected_at, notes, geo_lat, geo_lng, geo_accuracy, geo_address)
        VALUES (?, ?, NOW(), ?, ?, ?, ?, ?)
      ");
      $stmt->execute([
        $unitId, $staffUserId, $notes,
        $geoLat, $geoLng, $geoAccuracy, $geoAddress
      ]);

      $inspectionId = (int)db()->lastInsertId();

      foreach (self::normalizeFilesArray($beforeFiles) as $file) {
        if (!self::hasUpload($file)) continue;
        $path = self::saveImageUpload($file, 'before');
        self::insertPhotoRow($inspectionId, 'before', $path);
      }

      foreach (self::normalizeFilesArray($afterFiles) as $file) {
        if (!self::hasUpload($file)) continue;
        $path = self::saveImageUpload($file, 'after');
        self::insertPhotoRow($inspectionId, 'after', $path);
      }

      // ✅ Notify admins with address snippet
      try {
        $info = db()->prepare("
          SELECT u.unit_code, b.name AS building_name, usr.full_name AS staff_name
          FROM units u
          JOIN buildings b ON b.id = u.building_id
          LEFT JOIN users usr ON usr.id = ?
          WHERE u.id = ?
          LIMIT 1
        ");
        $info->execute([$staffUserId, $unitId]);
        $row = $info->fetch();

        $unitCode = $row['unit_code'] ?? ('Unit #' . $unitId);
        $building = $row['building_name'] ?? '';
        $staff    = $row['staff_name'] ?? ('User #' . $staffUserId);

        $locLine = '';
        if (!empty($geoAddress)) {
          $locLine = " Location: " . $geoAddress . ".";
        } elseif ($geoLat !== null && $geoLng !== null) {
          $locLine = " Location: {$geoLat}, {$geoLng}" . ($geoAccuracy ? " (±{$geoAccuracy}m)" : "") . ".";
        }

        Notification::notifyAdmins(
          'inspection_submitted',
          'New inspection submitted',
          "{$staff} submitted an inspection for {$building} • {$unitCode}." . $locLine,
          "/unit_inspections.php?unit_id=" . (int)$unitId,
          $staffUserId
        );
      } catch (Throwable $e) {}

      db()->commit();
      return $inspectionId;

    } catch (Throwable $e) {
      db()->rollBack();
      throw $e;
    }
  }

  private static function insertPhotoRow(int $inspectionId, string $type, string $filePath): void
  {
    $stmt = db()->prepare("
      INSERT INTO inspection_photos (inspection_id, photo_type, file_path, uploaded_at)
      VALUES (?, ?, ?, NOW())
    ");
    $stmt->execute([$inspectionId, $type, $filePath]);
  }

  private static function normalizeFilesArray(array $files): array
  {
    if (!isset($files['name'])) return [];
    if (!is_array($files['name'])) return [$files];

    $out = [];
    $count = count($files['name']);
    for ($i = 0; $i < $count; $i++) {
      $out[] = [
        'name'     => $files['name'][$i] ?? '',
        'type'     => $files['type'][$i] ?? '',
        'tmp_name' => $files['tmp_name'][$i] ?? '',
        'error'    => $files['error'][$i] ?? UPLOAD_ERR_NO_FILE,
        'size'     => $files['size'][$i] ?? 0,
      ];
    }
    return $out;
  }

  private static function hasUpload(array $file): bool
  {
    return isset($file['error']) && $file['error'] !== UPLOAD_ERR_NO_FILE;
  }

  private static function saveImageUpload(array $file, string $type): string
  {
    if (!in_array($type, ['before', 'after'], true)) throw new Exception("Invalid photo type.");
    if (!isset($file['error']) || $file['error'] !== UPLOAD_ERR_OK) throw new Exception("Upload error.");
    if (($file['size'] ?? 0) > MAX_UPLOAD_BYTES) throw new Exception("File is too large. Max " . MAX_UPLOAD_MB . "MB.");

    $tmp = $file['tmp_name'] ?? '';
    if (!$tmp || !is_uploaded_file($tmp)) throw new Exception("Invalid uploaded file.");

    $mime = mime_content_type($tmp);
    if (!in_array($mime, ALLOWED_IMAGE_MIME, true)) throw new Exception("Invalid image type. Allowed: JPG, PNG, WEBP.");

    $ext = 'jpg';
    if ($mime === 'image/png') $ext = 'png';
    if ($mime === 'image/webp') $ext = 'webp';

    $baseDir = ($type === 'before') ? UPLOAD_BEFORE_DIR : UPLOAD_AFTER_DIR;
    if (!is_dir($baseDir)) @mkdir($baseDir, 0775, true);

    $name = bin2hex(random_bytes(10)) . '_' . time() . '.' . $ext;
    $destAbs = rtrim($baseDir, '/\\') . DIRECTORY_SEPARATOR . $name;

    if (!move_uploaded_file($tmp, $destAbs)) throw new Exception("Failed to save uploaded file.");
    return 'uploads/' . $type . '/' . $name;
  }
}
