<?php

namespace SSCI\Classes;

/**
 * Patrol Controller
 * Handles patrol-related operations and business logic
 */
class PatrolController
{
    private Database $db;
    private Notification $notification;

    public function __construct(Database $db, Notification $notification = null)
    {
        $this->db = $db;
        $this->notification = $notification;
    }

    /**
     * Get patrol dashboard data for a post
     */
    public function getDashboard(int $postId): array
    {
        try {
            $patrol = new Patrol($this->db);
            
            return [
                'success' => true,
                'current_status' => $patrol->getCurrentHourStatus($postId),
                'today_summary' => $patrol->getTodaysSummary($postId),
                'history' => $patrol->getPatrolHistory($postId, 7),
                'countdown' => $patrol->getCountdownToNextHour(),
                'last_scan' => $patrol->getLastScanInfo($postId),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Record a patrol scan
     */
    public function recordScan(int $postId, string $qrCode, int $guardId, ?float $latitude, ?float $longitude, string $deviceInfo = ''): array
    {
        try {
            // Validate guard is assigned to post
            $assignment = $this->db->fetch(
                "SELECT id FROM guard_post_assignments 
                 WHERE post_id = ? AND guard_id = ? AND end_date IS NULL",
                [$postId, $guardId]
            );

            if (!$assignment) {
                return [
                    'success' => false,
                    'message' => 'Guard not assigned to this post',
                ];
            }

            $patrol = new Patrol($this->db);
            $result = $patrol->recordScan($postId, $qrCode, $guardId, $latitude, $longitude, $deviceInfo);

            if ($result['success']) {
                // Send notification to guard and supervisors
                $guard = $this->db->fetch("SELECT name, email, phone FROM users WHERE id = ?", [$guardId]);
                $point = $this->db->fetch("SELECT point_name FROM patrol_points WHERE qr_code = ?", [$qrCode]);

                if ($guard && $point) {
                    $this->notification->reset()
                        ->forUser($guardId)
                        ->setTitle('Scan Recorded ✓')
                        ->setMessage("Patrol point '{$point['point_name']}' scanned at " . date('H:i'))
                        ->setType('success')
                        ->via(['push', 'in-app'])
                        ->send();
                }
            }

            return $result;
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Get patrol points for a post
     */
    public function getPatrolPoints(int $postId): array
    {
        try {
            $points = $this->db->fetchAll(
                "SELECT * FROM patrol_points 
                 WHERE post_id = ? AND is_active = 1 
                 ORDER BY point_name ASC",
                [$postId]
            );

            return [
                'success' => true,
                'data' => $points,
                'count' => count($points),
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Create a patrol point
     */
    public function createPatrolPoint(int $postId, string $pointName, float $latitude, float $longitude, string $description = ''): array
    {
        try {
            // Check max 4 points per post
            $count = $this->db->fetch(
                "SELECT COUNT(*) as cnt FROM patrol_points WHERE post_id = ? AND is_active = 1",
                [$postId]
            );

            if ($count['cnt'] >= 4) {
                return [
                    'success' => false,
                    'message' => 'Maximum 4 patrol points per post',
                ];
            }

            // Generate unique QR code
            $qrCode = 'PATROL-' . $postId . '-' . bin2hex(random_bytes(8));

            $this->db->query(
                "INSERT INTO patrol_points (post_id, point_name, qr_code, latitude, longitude, location_description, is_active, created_at) 
                 VALUES (?, ?, ?, ?, ?, ?, 1, NOW())",
                [$postId, $pointName, $qrCode, $latitude, $longitude, $description]
            );

            return [
                'success' => true,
                'id' => $this->db->lastInsertId(),
                'qr_code' => $qrCode,
                'message' => 'Patrol point created successfully',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Update a patrol point
     */
    public function updatePatrolPoint(int $pointId, string $pointName, float $latitude, float $longitude, string $description = '', bool $isActive = true): array
    {
        try {
            $this->db->query(
                "UPDATE patrol_points 
                 SET point_name = ?, latitude = ?, longitude = ?, location_description = ?, is_active = ?, updated_at = NOW() 
                 WHERE id = ?",
                [$pointName, $latitude, $longitude, $description, $isActive ? 1 : 0, $pointId]
            );

            return [
                'success' => true,
                'message' => 'Patrol point updated successfully',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Delete a patrol point
     */
    public function deletePatrolPoint(int $pointId): array
    {
        try {
            $this->db->query(
                "UPDATE patrol_points SET is_active = 0, updated_at = NOW() WHERE id = ?",
                [$pointId]
            );

            return [
                'success' => true,
                'message' => 'Patrol point deleted successfully',
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Get patrol report for date range
     */
    public function getPatrolReport(int $postId, string $startDate, string $endDate): array
    {
        try {
            $data = $this->db->fetchAll(
                "SELECT 
                    patrol_date,
                    COUNT(*) as total_hours,
                    SUM(CASE WHEN status = 'Completed' THEN 1 ELSE 0 END) as completed,
                    SUM(CASE WHEN status = 'Incomplete' THEN 1 ELSE 0 END) as incomplete,
                    SUM(CASE WHEN status = 'Missed' THEN 1 ELSE 0 END) as missed,
                    AVG(score) as avg_score,
                    AVG(completion_percentage) as avg_completion
                 FROM patrols
                 WHERE post_id = ? AND patrol_date BETWEEN ? AND ?
                 GROUP BY patrol_date
                 ORDER BY patrol_date DESC",
                [$postId, $startDate, $endDate]
            );

            return [
                'success' => true,
                'data' => $data,
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }

    /**
     * Get guards assigned to post with their patrol stats
     */
    public function getPostGuardsStats(int $postId, ?string $date = null): array
    {
        try {
            $date = $date ?? date('Y-m-d');

            $guards = $this->db->fetchAll(
                "SELECT DISTINCT 
                    u.id,
                    u.name,
                    u.phone,
                    COUNT(DISTINCT ps.id) as total_scans,
                    COUNT(DISTINCT DATE(ps.scan_timestamp)) as days_assigned,
                    MAX(ps.scan_timestamp) as last_scan
                 FROM users u
                 JOIN guard_post_assignments gpa ON u.id = gpa.guard_id
                 LEFT JOIN patrol_scans ps ON u.id = ps.guard_id AND DATE(ps.scan_timestamp) = ?
                 WHERE gpa.post_id = ? AND (gpa.end_date IS NULL OR gpa.end_date >= ?)
                 GROUP BY u.id, u.name, u.phone
                 ORDER BY last_scan DESC",
                [$date, $postId, $date]
            );

            return [
                'success' => true,
                'data' => $guards,
            ];
        } catch (\Exception $e) {
            return [
                'success' => false,
                'message' => $e->getMessage(),
            ];
        }
    }
}
