<?php

class DashboardService {
    private $pdo;
    private $storeId;

    public function __construct($pdo, $storeId) {
        $this->pdo = $pdo;
        $this->storeId = (int)$storeId;
    }

    /**
     * Calculates start and end dates based on period key
     */
    public function getDateRange(string $period, ?string $customFrom = null, ?string $customTo = null): array {
        $today = date('Y-m-d');
        
        switch ($period) {
            case 'yesterday':
                return [
                    'from' => date('Y-m-d', strtotime('-1 day')),
                    'to' => date('Y-m-d', strtotime('-1 day')),
                    'label' => 'Ontem'
                ];
            case 'week':
                return [
                    'from' => date('Y-m-d', strtotime('monday this week')),
                    'to' => $today,
                    'label' => 'Esta Semana'
                ];
            case 'month':
                return [
                    'from' => date('Y-m-01'),
                    'to' => $today,
                    'label' => 'Este Mês'
                ];
            case 'last_month':
                return [
                    'from' => date('Y-m-01', strtotime('first day of last month')),
                    'to' => date('Y-m-t', strtotime('last day of last month')),
                    'label' => 'Mês Passado'
                ];
            case 'custom':
                return [
                    'from' => $customFrom ?? $today,
                    'to' => $customTo ?? $today,
                    'label' => date('d/m', strtotime($customFrom ?? $today)) . ' - ' . date('d/m', strtotime($customTo ?? $today))
                ];
            case 'today':
            default:
                return [
                    'from' => $today,
                    'to' => $today,
                    'label' => 'Hoje'
                ];
        }
    }

    /**
     * Get Service-based KPIs
     */
    public function getServiceKPIs(string $dateFrom, string $dateTo): array {
        $kpis = [
            'appointments_today' => 0,
            'revenue_today' => 0,
            'clients_active' => 0,
            'pending_appointments' => 0
        ];

        try {
            // Appointments Today
            $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM appointments WHERE store_id = ? AND DATE(appointment_date) BETWEEN ? AND ?");
            $stmt->execute([$this->storeId, $dateFrom, $dateTo]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['appointments_today'] = $row['total'] ?? 0;

            // Revenue
            $stmt = $this->pdo->prepare("SELECT COALESCE(SUM(total_amount), 0) as total FROM appointments WHERE store_id = ? AND DATE(appointment_date) BETWEEN ? AND ? AND status = 'completed'");
            $stmt->execute([$this->storeId, $dateFrom, $dateTo]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['revenue_today'] = $row['total'] ?? 0;

            // Total Clients
            $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM clients WHERE store_id = ?");
            $stmt->execute([$this->storeId]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['clients_active'] = $row['total'] ?? 0;

            // Pending Appointments
            $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM appointments WHERE store_id = ? AND DATE(appointment_date) BETWEEN ? AND ? AND status IN ('pending', 'confirmed')");
            $stmt->execute([$this->storeId, $dateFrom, $dateTo]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['pending_appointments'] = $row['total'] ?? 0;

        } catch (Exception $e) {
            error_log("DashboardService::getServiceKPIs Error: " . $e->getMessage());
        }

        return $kpis;
    }

    /**
     * Get Retail-based KPIs
     */
    public function getRetailKPIs(string $dateFrom, string $dateTo): array {
        $kpis = [
            'orders_pending' => 0,
            'revenue_today' => 0,
            'products_low_stock' => 0,
            'visitors_today' => 0
        ];

        try {
            // Pending Orders
            $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM orders WHERE store_id = ? AND DATE(created_at) BETWEEN ? AND ? AND status IN ('pending', 'awaiting_payment')");
            $stmt->execute([$this->storeId, $dateFrom, $dateTo]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['orders_pending'] = $row['total'] ?? 0;

            // Revenue
            $stmt = $this->pdo->prepare("SELECT COALESCE(SUM(total_amount), 0) as total FROM orders WHERE store_id = ? AND DATE(created_at) BETWEEN ? AND ? AND status IN ('completed', 'delivered', 'paid')");
            $stmt->execute([$this->storeId, $dateFrom, $dateTo]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['revenue_today'] = $row['total'] ?? 0;

            // Low Stock
            $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM products WHERE store_id = ? AND stock_quantity <= 5 AND is_active = 1");
            $stmt->execute([$this->storeId]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['products_low_stock'] = $row['total'] ?? 0;

            // Visitors
            $stmt = $this->pdo->prepare("SELECT COUNT(DISTINCT visitor_ip) as total FROM store_visitors WHERE store_id = ? AND DATE(visited_at) BETWEEN ? AND ?");
            $stmt->execute([$this->storeId, $dateFrom, $dateTo]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            $kpis['visitors_today'] = $row['total'] ?? 0;

        } catch (Exception $e) {
            error_log("DashboardService::getRetailKPIs Error: " . $e->getMessage());
        }

        return $kpis;
    }

    /**
     * Get upcoming appointments
     */
    public function getNextAppointments(int $limit = 3): array {
        try {
            $stmt = $this->pdo->prepare("SELECT a.*, c.name as client_name, s.name as service_name FROM appointments a LEFT JOIN clients c ON a.client_id = c.id LEFT JOIN services s ON a.service_id = s.id WHERE a.store_id = ? AND a.appointment_date >= CURDATE() ORDER BY a.appointment_date ASC LIMIT ?");
            // LIMIT param needs to be int for PDO emulation sometimes, but binding as param is safer
            $stmt->bindValue(1, $this->storeId, PDO::PARAM_INT);
            $stmt->bindValue(2, $limit, PDO::PARAM_INT);
            $stmt->execute();
            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
            return $results ?: [];
        } catch (Exception $e) {
            error_log("DashboardService::getNextAppointments Error: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Get recent orders
     */
    public function getRecentOrders(int $limit = 3): array {
        try {
            $stmt = $this->pdo->prepare("SELECT o.*, COALESCE(o.customer_name, c.name) as client_name FROM orders o LEFT JOIN clients c ON o.customer_id = c.id WHERE o.store_id = ? ORDER BY o.created_at DESC LIMIT ?");
            $stmt->bindValue(1, $this->storeId, PDO::PARAM_INT);
            $stmt->bindValue(2, $limit, PDO::PARAM_INT);
            $stmt->execute();
            $results = $stmt->fetchAll(PDO::FETCH_ASSOC);
            return $results ?: [];
        } catch (Exception $e) {
            error_log("DashboardService::getRecentOrders Error: " . $e->getMessage());
            return [];
        }
    }

    /**
     * Get total active items (services or products)
     */
    public function getTotalItems(string $type): int {
        try {
            // Strictly handle table selection to avoid invalid variable interpolation policies
            // even though previous validation was safe.
            $sql = "";
            if ($type === 'service') {
                $sql = "SELECT COUNT(*) as total FROM services WHERE store_id = ? AND is_active = 1";
            } elseif ($type === 'product') { // assuming 'product' maps to products, logic in dashboard used logic: businessType=='service'?'services':'products'
                $sql = "SELECT COUNT(*) as total FROM products WHERE store_id = ? AND is_active = 1";
            } else {
                 // Fallback for strictness if input doesn't match known types
                 // The calling code passes businessType which is 'service' or 'retail'.
                 // Wait, original code was: $tableName = $type === 'service' ? 'services' : 'products';
                 // If type is 'retail', original code used 'products'.
                 $sql = "SELECT COUNT(*) as total FROM products WHERE store_id = ? AND is_active = 1";
            }
            
            // Logic correction based on previous implementation intent:
            // if type == service -> services, else -> products.
            if ($type === 'service') {
                $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM services WHERE store_id = ? AND is_active = 1");
            } else {
                $stmt = $this->pdo->prepare("SELECT COUNT(*) as total FROM products WHERE store_id = ? AND is_active = 1");
            }

            $stmt->execute([$this->storeId]);
            $row = $stmt->fetch(PDO::FETCH_ASSOC);
            return $row['total'] ?? 0;
        } catch (Exception $e) {
            return 0; // Table might not exist or other error
        }
    }

    /**
     * Calculate Trial Days Left
     */
    public function getTrialDaysLeft(array $store): int {
        if (($store['status'] ?? '') === 'trial' && !empty($store['trial_ends_at'])) {
            try {
                $trialEnd = new DateTime($store['trial_ends_at']);
                $now = new DateTime();
                $diff = $now->diff($trialEnd);
                return $diff->invert ? 0 : $diff->days;
            } catch (Exception $e) {
                return 0;
            }
        }
        return 0;
    }
}
