<?php
require_once __DIR__ . '/db.php';
if (session_status() !== PHP_SESSION_ACTIVE) session_start();
$action = $_GET['action'] ?? $_POST['action'] ?? '';
$input = json_decode(file_get_contents('php://input'), true) ?: [];

try {
    switch ($action) {
        case 'login': {
            $password = (string)($input['password'] ?? '');
            $hash = app_setting('access_password_hash');
            if (!$hash) {
                $hash = password_hash(DEFAULT_PASSWORD, PASSWORD_DEFAULT);
                set_app_setting('access_password_hash', $hash);
            }
            if (password_verify($password, $hash)) {
                $_SESSION['logged_in'] = true;
                json_response(['ok' => true]);
            }
            json_response(['ok' => false, 'error' => 'Clave incorrecta'], 403);
        }
        case 'logout': {
            session_destroy();
            json_response(['ok' => true]);
        }
        case 'bootstrap': {
            require_login();
            $emails = json_decode(app_setting('emails', '[]'), true) ?: [];
            $pumps = db()->query('SELECT id, name, pump_type, faces, active FROM pumps WHERE active=1 ORDER BY id ASC')->fetchAll();
            json_response([
                'ok' => true,
                'config' => [
                    'station_name' => app_setting('station_name', 'Copec Ogana 20830'),
                    'emails' => $emails,
                ],
                'pumps' => $pumps,
            ]);
        }
        case 'save_config': {
            require_login();
            $station = trim((string)($input['station_name'] ?? 'Copec Ogana 20830'));
            $emails = array_values(array_filter(array_map('trim', $input['emails'] ?? [])));
            set_app_setting('station_name', $station);
            set_app_setting('emails', json_encode($emails, JSON_UNESCAPED_UNICODE));
            if (!empty($input['new_password'])) {
                set_app_setting('access_password_hash', password_hash((string)$input['new_password'], PASSWORD_DEFAULT));
            }
            json_response(['ok' => true]);
        }
        case 'save_pumps': {
            require_login();
            $pumps = $input['pumps'] ?? [];
            db()->beginTransaction();
            db()->exec('UPDATE pumps SET active=0');
            foreach ($pumps as $p) {
                $id = (int)($p['id'] ?? 0);
                $name = trim((string)($p['name'] ?? 'Surtidor'));
                $type = trim((string)($p['pump_type'] ?? 'Multiproducto'));
                $faces = max(1, min(4, (int)($p['faces'] ?? 2)));
                if ($id > 0) {
                    $stmt = db()->prepare('UPDATE pumps SET name=?, pump_type=?, faces=?, active=1 WHERE id=?');
                    $stmt->execute([$name, $type, $faces, $id]);
                    if ($stmt->rowCount() === 0) {
                        $ins = db()->prepare('INSERT INTO pumps(name,pump_type,faces,active) VALUES(?,?,?,1)');
                        $ins->execute([$name, $type, $faces]);
                    }
                } else {
                    $ins = db()->prepare('INSERT INTO pumps(name,pump_type,faces,active) VALUES(?,?,?,1)');
                    $ins->execute([$name, $type, $faces]);
                }
            }
            db()->commit();
            json_response(['ok' => true]);
        }
        case 'save_review': {
            require_login();
            $type = (string)($input['review_type'] ?? '');
            if (!in_array($type, ['surtidores','generador','lavado'], true)) json_response(['ok'=>false,'error'=>'Tipo inválido'], 422);
            $date = (string)($input['review_date'] ?? date('Y-m-d'));
            $responsible = trim((string)($input['responsible_name'] ?? ''));
            if ($responsible === '') json_response(['ok'=>false,'error'=>'Debe ingresar responsable'], 422);
            $email = trim((string)($input['responsible_email'] ?? ''));
            $data = $input['data'] ?? [];
            $signaturePath = save_base64_image($input['signature_image'] ?? null, 'observaciones', 'firma');
            $photosToSave = [];

            if ($type === 'lavado') {
                if (empty($data['numeral_lavado']) || empty($data['numeral_aspirado'])) json_response(['ok'=>false,'error'=>'Debe ingresar numerales de lavado y aspirado'], 422);
                if (empty($data['foto_numeral_lavado']) || empty($data['foto_numeral_aspirado'])) json_response(['ok'=>false,'error'=>'Debe adjuntar foto de cada numeral'], 422);
                $pathLavado = save_base64_image($data['foto_numeral_lavado'], 'numerales', 'numeral_lavado');
                $pathAspirado = save_base64_image($data['foto_numeral_aspirado'], 'numerales', 'numeral_aspirado');
                $data['foto_numeral_lavado_path'] = $pathLavado;
                $data['foto_numeral_aspirado_path'] = $pathAspirado;
                unset($data['foto_numeral_lavado'], $data['foto_numeral_aspirado']);
                $photosToSave[] = ['foto_numeral_lavado', $pathLavado];
                $photosToSave[] = ['foto_numeral_aspirado', $pathAspirado];
            }

            if (!empty($data['fotos_observacion']) && is_array($data['fotos_observacion'])) {
                $saved = [];
                foreach ($data['fotos_observacion'] as $idx => $img) {
                    $path = save_base64_image($img, 'observaciones', 'obs');
                    if ($path) { $saved[] = $path; $photosToSave[] = ['observacion', $path]; }
                }
                $data['fotos_observacion_paths'] = $saved;
                unset($data['fotos_observacion']);
            }

            $stmt = db()->prepare('INSERT INTO reviews(review_type, review_date, responsible_name, responsible_email, data_json, signature_image) VALUES(?,?,?,?,?,?)');
            $stmt->execute([$type, $date, $responsible, $email ?: null, json_encode($data, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), $signaturePath]);
            $reviewId = (int)db()->lastInsertId();
            foreach ($photosToSave as [$photoType, $path]) {
                if (!$path) continue;
                $pstmt = db()->prepare('INSERT INTO review_photos(review_id, photo_type, file_path) VALUES(?,?,?)');
                $pstmt->execute([$reviewId, $photoType, $path]);
            }

            $pdfPath = null;
            $emailResult = ['sent' => false, 'error' => null];
            try {
                $pdfPath = generate_review_pdf($reviewId, $type, $date, $responsible, $data, $signaturePath);
                $emailResult = send_review_email($reviewId, $type, $date, $responsible, $email ?: null, $pdfPath);
            } catch (Throwable $mailError) {
                $emailResult = ['sent' => false, 'error' => $mailError->getMessage()];
            }
            $up = db()->prepare('UPDATE reviews SET pdf_path=?, email_sent=?, email_error=?, status=? WHERE id=?');
            $up->execute([$pdfPath, !empty($emailResult['sent']) ? 1 : 0, $emailResult['error'] ?? null, !empty($emailResult['sent']) ? 'enviado' : 'guardado_sin_correo', $reviewId]);

            json_response(['ok' => true, 'id' => $reviewId, 'pdf_path' => $pdfPath, 'email_sent' => !empty($emailResult['sent']), 'email_error' => $emailResult['error'] ?? null]);
        }
        case 'list_reviews': {
            require_login();
            $type = $_GET['type'] ?? '';
            $where = '';
            $params = [];
            if (in_array($type, ['surtidores','generador','lavado'], true)) { $where = 'WHERE review_type=?'; $params[] = $type; }
            $stmt = db()->prepare("SELECT id, review_type, review_date, responsible_name, created_at, data_json, pdf_path, email_sent, email_error, status FROM reviews $where ORDER BY review_date DESC, id DESC LIMIT 200");
            $stmt->execute($params);
            $rows = $stmt->fetchAll();
            foreach ($rows as &$r) $r['data'] = json_decode($r['data_json'], true) ?: [];
            json_response(['ok' => true, 'reviews' => $rows]);
        }
        case 'dashboard_lavado': {
            require_login();
            $month = $_GET['month'] ?? date('Y-m');
            $stmt = db()->prepare("SELECT id, review_date, data_json FROM reviews WHERE review_type='lavado' AND DATE_FORMAT(review_date, '%Y-%m')=? ORDER BY review_date ASC, id ASC");
            $stmt->execute([$month]);
            $rows = $stmt->fetchAll();
            $items = [];
            foreach ($rows as $r) {
                $d = json_decode($r['data_json'], true) ?: [];
                $items[] = [
                    'id' => (int)$r['id'],
                    'date' => $r['review_date'],
                    'lavado' => (int)($d['numeral_lavado'] ?? 0),
                    'aspirado' => (int)($d['numeral_aspirado'] ?? 0),
                    'fichas_lavado' => (int)($d['fichas_lavado'] ?? 0),
                    'fichas_aspirado' => (int)($d['fichas_aspirado'] ?? 0),
                    'incidente' => !empty($d['incidente']),
                    'foto_lavado' => $d['foto_numeral_lavado_path'] ?? null,
                    'foto_aspirado' => $d['foto_numeral_aspirado_path'] ?? null,
                ];
            }
            $tramos = [];
            for ($i=1; $i<count($items); $i++) {
                $prev = $items[$i-1]; $cur = $items[$i];
                $usoLavado = $cur['lavado'] - $prev['lavado'];
                $usoAspirado = $cur['aspirado'] - $prev['aspirado'];
                $tramos[] = [
                    'desde' => $prev['date'], 'hasta' => $cur['date'],
                    'uso_lavado' => $usoLavado, 'uso_aspirado' => $usoAspirado,
                    'uso_total' => $usoLavado + $usoAspirado,
                    'fichas_total' => $cur['fichas_lavado'] + $cur['fichas_aspirado'],
                    'diferencia' => ($usoLavado + $usoAspirado) - ($cur['fichas_lavado'] + $cur['fichas_aspirado']),
                    'valido' => $usoLavado >= 0 && $usoAspirado >= 0,
                ];
            }
            $valid = array_values(array_filter($tramos, function($t) { return $t['valido']; }));
            $days = count($valid);
            $totalUso = array_sum(array_column($valid, 'uso_total'));
            $avg = $days > 0 ? round($totalUso / $days, 1) : 0;
            $daysInMonth = (int)date('t', strtotime($month . '-01'));
            json_response(['ok'=>true, 'items'=>$items, 'tramos'=>$tramos, 'summary'=>[
                'registros' => count($items),
                'dias_calculables' => $days,
                'uso_real_total' => $totalUso,
                'promedio_diario' => $avg,
                'proyeccion_mes' => round($avg * $daysInMonth),
                'requiere_minimo_dos_registros' => count($items) < 2,
                'incidentes' => count(array_filter($items, function($i) { return $i['incidente']; })),
            ]]);
        }
        case 'resend_email': {
            require_login();
            $id = (int)($input['id'] ?? 0);
            if ($id <= 0) json_response(['ok'=>false,'error'=>'ID inválido'], 422);
            $stmt = db()->prepare('SELECT * FROM reviews WHERE id=? LIMIT 1');
            $stmt->execute([$id]);
            $r = $stmt->fetch();
            if (!$r) json_response(['ok'=>false,'error'=>'Registro no encontrado'], 404);
            $data = json_decode($r['data_json'], true) ?: [];
            $pdfPath = $r['pdf_path'];
            if (!$pdfPath || !is_file(__DIR__ . '/' . $pdfPath)) {
                $pdfPath = generate_review_pdf((int)$r['id'], $r['review_type'], $r['review_date'], $r['responsible_name'], $data, $r['signature_image']);
            }
            try {
                $emailResult = send_review_email((int)$r['id'], $r['review_type'], $r['review_date'], $r['responsible_name'], $r['responsible_email'], $pdfPath);
            } catch (Throwable $mailError) {
                $emailResult = ['sent'=>false, 'error'=>$mailError->getMessage()];
            }
            $up = db()->prepare('UPDATE reviews SET pdf_path=?, email_sent=?, email_error=?, status=? WHERE id=?');
            $up->execute([$pdfPath, !empty($emailResult['sent']) ? 1 : 0, $emailResult['error'] ?? null, !empty($emailResult['sent']) ? 'enviado' : 'guardado_sin_correo', $id]);
            json_response(['ok'=>true, 'pdf_path'=>$pdfPath, 'email_sent'=>!empty($emailResult['sent']), 'email_error'=>$emailResult['error'] ?? null]);
        }
        default:
            json_response(['ok' => false, 'error' => 'Acción no válida'], 404);
    }
} catch (Throwable $e) {
    json_response(['ok' => false, 'error' => $e->getMessage()], 500);
}
