<?php

class WeeklyReportsController extends BaseController
{
    /** @var PDO */
    protected $pdo;

    /** @var int|null */
    protected $userId;

    /** @var int|null */
    protected $tenantId;

    public function __construct($pdo = null)
    {
        parent::__construct();
        $this->pdo      = $pdo ?: Database::getConnection();
        $this->userId   = $_SESSION['user_id']   ?? null;
        $this->tenantId = $_SESSION['tenant_id'] ?? null;
    }

    /**
     * Main Weekly Reports page (SkyBlue layout)
     */
    public function index()
    {
        $this->authCheck();

        $currentWeek = $this->getCurrentWeek();

        $this->render('pages/weekly-reports', [
            'currentWeek' => $currentWeek,
            'currentPage' => 'weekly-reports',
            'pageTitle'   => 'Weekly Reports - LeadIntelligence AI',
        ]);
    }


    /**
     * Return tasks for this tenant (optional week filter).
     * NOTE: current Tasks module has no assignments, so we don't filter by user.
     */
    public function getUserTasks($week = null)
    {
        $this->authCheck();

        $sql = "
            SELECT
                t.id   AS task_id,
                t.title,
                t.description,
                t.status,
                t.priority,
                DATE_FORMAT(t.due_date, '%Y-%m-%d') AS due_date,
                t.created_at
            FROM tasks t
            WHERE t.tenant_id = :tenant_id
        ";

        $params = [
            ':tenant_id' => $this->tenantId,
        ];

        // Optional filter by due_date week (ISO week)
        $useWeek = $week && $this->validateWeekFormat($week);
        if ($useWeek) {
            [$year, $weekNum] = explode('-W', $week);
            $sql .= " AND YEARWEEK(t.due_date, 1) = :yearweek";
            $params[':yearweek'] = (int)($year . $weekNum);
        }

        $sql .= "
            ORDER BY 
                CASE t.priority 
                    WHEN 'high' THEN 1 
                    WHEN 'medium' THEN 2 
                    WHEN 'low' THEN 3 
                    ELSE 4 
                END,
                t.due_date IS NULL ASC,
                t.due_date ASC,
                t.created_at DESC
        ";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute($params);
            $tasks = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

            return $this->json([
                'success' => true,
                'data'    => $tasks,
                'count'   => count($tasks),
                'filters' => [
                    'week'      => $week,
                    'tenant_id' => $this->tenantId,
                ],
            ]);
        } catch (Exception $e) {
            error_log("WeeklyReportsController::getUserTasks error: " . $e->getMessage());

            return $this->json([
                'success' => false,
                'message' => 'Unable to fetch tasks. Please try again.',
            ], 500);
        }
    }

    /**
     * Convenience alias: all tasks (no week filter)
     */
    public function getAllUserTasks()
    {
        return $this->getUserTasks(null);
    }

    /**
     * Handle POST from weekly-report form (AJAX).
     */
    public function submit()
    {
        $this->authCheck();

        if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
            return $this->json([
                'success' => false,
                'message' => 'Invalid request method',
            ], 405);
        }

        $data = [
            'week'            => $_POST['week'] ?? '',
            'accomplishments' => $_POST['accomplishments'] ?? '',
            'status'          => $_POST['status'] ?? 'draft',
            'linked_tasks'    => isset($_POST['linked_tasks']) && is_array($_POST['linked_tasks'])
                ? $_POST['linked_tasks']
                : [],
        ];

        return $this->submitAccomplishmentsInternal($data);
    }

    /**
     * Internal logic to create/update a weekly report.
     */
    private function submitAccomplishmentsInternal(array $data)
    {
        $this->authCheck();

        try {
            if (empty($data['week']) || empty($data['accomplishments'])) {
                return $this->json([
                    'success' => false,
                    'message' => 'Week and accomplishments are required',
                ], 400);
            }

            if (!$this->validateWeekFormat((string)$data['week'])) {
                return $this->json([
                    'success' => false,
                    'message' => 'Invalid week format. Use YYYY-WW (e.g., 2025-W41)',
                ], 400);
            }

            // Does a report already exist for this user+week?
            $checkSql = "
                SELECT id, status 
                FROM weekly_reports 
                WHERE tenant_id = :tenant_id 
                  AND user_id   = :user_id 
                  AND week      = :week
                LIMIT 1
            ";

            $check = $this->pdo->prepare($checkSql);
            $check->execute([
                ':tenant_id' => $this->tenantId,
                ':user_id'   => $this->userId,
                ':week'      => (string)$data['week'],
            ]);

            $existingReport = $check->fetch(PDO::FETCH_ASSOC);

            if ($existingReport) {
                if (($existingReport['status'] ?? '') === 'approved') {
                    return $this->json([
                        'success' => false,
                        'message' => 'Cannot modify an approved weekly report',
                    ], 409);
                }

                return $this->updateExistingReport((int)$existingReport['id'], $data);
            }

            // Insert new weekly report
            $insertSql = "
                INSERT INTO weekly_reports 
                    (tenant_id, user_id, week, accomplishments, status, created_at, updated_at)
                VALUES 
                    (:tenant_id, :user_id, :week, :accomplishments, :status, NOW(), NOW())
            ";

            $status = (string)($data['status'] ?? 'draft');

            $ins = $this->pdo->prepare($insertSql);
            $ins->execute([
                ':tenant_id'       => $this->tenantId,
                ':user_id'         => $this->userId,
                ':week'            => (string)$data['week'],
                ':accomplishments' => (string)$data['accomplishments'],
                ':status'          => $status,
            ]);

            $reportId = (int)$this->pdo->lastInsertId();

            // Link tasks if provided
            $linkedCount = 0;
            if (!empty($data['linked_tasks']) && is_array($data['linked_tasks'])) {
                $linkedCount = $this->linkTasksToReport($reportId, $data['linked_tasks']);
            }

            $this->handlePostSubmissionActions($reportId, $status);

            return $this->json([
                'success'            => true,
                'message'            => $status === 'draft'
                    ? 'Weekly accomplishments saved as draft'
                    : 'Weekly accomplishments submitted successfully',
                'report_id'          => $reportId,
                'linked_tasks_count' => $linkedCount,
            ]);
        } catch (Exception $e) {
            error_log("WeeklyReportsController::submitAccomplishments error: " . $e->getMessage());

            return $this->json([
                'success' => false,
                'message' => 'Unable to save accomplishments. Please try again.',
            ], 500);
        }
    }

    /**
     * Update an existing report.
     */
    private function updateExistingReport(int $reportId, array $data)
    {
        $status = (string)($data['status'] ?? 'draft');

        $updateSql = "
            UPDATE weekly_reports 
            SET accomplishments = :accomplishments,
                status          = :status,
                updated_at      = NOW()
            WHERE id        = :report_id
              AND tenant_id = :tenant_id 
              AND user_id   = :user_id
        ";

        $upd = $this->pdo->prepare($updateSql);
        $upd->execute([
            ':accomplishments' => (string)$data['accomplishments'],
            ':status'          => $status,
            ':report_id'       => $reportId,
            ':tenant_id'       => $this->tenantId,
            ':user_id'         => $this->userId,
        ]);

        // Update task links if the field was present
        $linkedCount = 0;
        if (array_key_exists('linked_tasks', $data)) {
            $del = $this->pdo->prepare("
                DELETE FROM report_task_links 
                WHERE report_id = :report_id
            ");
            $del->execute([':report_id' => $reportId]);

            if (!empty($data['linked_tasks']) && is_array($data['linked_tasks'])) {
                $linkedCount = $this->linkTasksToReport($reportId, $data['linked_tasks']);
            }
        }

        $this->handlePostSubmissionActions($reportId, $status);

        return $this->json([
            'success'            => true,
            'message'            => 'Weekly report updated successfully',
            'report_id'          => $reportId,
            'linked_tasks_count' => $linkedCount,
        ]);
    }

    /**
     * Hook for notifications (currently stubbed).
     */
    private function handlePostSubmissionActions(int $reportId, string $status): void
    {
        // Later: email / notification hooks can go here.
    }

    /**
     * Link tasks to a weekly report.
     */
    private function linkTasksToReport(int $reportId, array $taskIds): int
    {
        $insertSql = "
            INSERT INTO report_task_links 
                (report_id, task_id, created_at)
            VALUES 
                (:report_id, :task_id, NOW())
        ";

        $ins         = $this->pdo->prepare($insertSql);
        $linkedCount = 0;

        foreach ($taskIds as $taskIdRaw) {
            $taskId = (int)$taskIdRaw;
            if ($taskId <= 0) {
                continue;
            }

            // Check task belongs to tenant
            $validateSql = "
                SELECT 1
                FROM tasks
                WHERE id = :task_id
                  AND tenant_id = :tenant_id
                LIMIT 1
            ";

            $val = $this->pdo->prepare($validateSql);
            $val->execute([
                ':task_id'   => $taskId,
                ':tenant_id' => $this->tenantId,
            ]);

            if ($val->fetchColumn()) {
                try {
                    $ins->execute([
                        ':report_id' => $reportId,
                        ':task_id'   => $taskId,
                    ]);
                    $linkedCount++;
                } catch (Exception $e) {
                    if (strpos($e->getMessage(), 'Duplicate') === false) {
                        error_log("WeeklyReportsController::linkTasksToReport error: " . $e->getMessage());
                    }
                }
            }
        }

        return $linkedCount;
    }

    /**
     * Get weekly report for a given week (JSON).
     */
    public function getWeeklyReport($week)
    {
        $this->authCheck();

        if (!$this->validateWeekFormat($week)) {
            return $this->json([
                'success' => false,
                'message' => 'Invalid week format. Use YYYY-WW',
            ], 400);
        }

        $sql = "
            SELECT 
                wr.id,
                wr.week,
                wr.accomplishments,
                wr.status,
                wr.created_at,
                wr.updated_at,
                GROUP_CONCAT(rtl.task_id) AS linked_task_ids
            FROM weekly_reports wr
            LEFT JOIN report_task_links rtl ON wr.id = rtl.report_id
            WHERE wr.tenant_id = :tenant_id 
              AND wr.user_id   = :user_id 
              AND wr.week      = :week
            GROUP BY wr.id
        ";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->execute([
                ':tenant_id' => $this->tenantId,
                ':user_id'   => $this->userId,
                ':week'      => $week,
            ]);

            $report = $stmt->fetch(PDO::FETCH_ASSOC);

            if ($report) {
                $report['linked_task_ids'] = !empty($report['linked_task_ids'])
                    ? array_map('intval', explode(',', (string)$report['linked_task_ids']))
                    : [];
            }

            return $this->json([
                'success' => true,
                'data'    => $report ?: null,
                'exists'  => !empty($report),
            ]);
        } catch (Exception $e) {
            error_log("WeeklyReportsController::getWeeklyReport error: " . $e->getMessage());

            return $this->json([
                'success' => false,
                'message' => 'Unable to fetch weekly report. Please try again.',
            ], 500);
        }
    }

    /**
     * Report history for this user (JSON).
     */
    public function getReportHistory($limit = 10)
    {
        $this->authCheck();

        $limit = (int)$limit > 0 ? (int)$limit : 10;

        $sql = "
            SELECT 
                wr.id,
                wr.week,
                wr.status,
                wr.created_at,
                wr.updated_at,
                COUNT(rtl.task_id)          AS linked_tasks_count,
                LENGTH(wr.accomplishments)  AS content_length
            FROM weekly_reports wr
            LEFT JOIN report_task_links rtl ON wr.id = rtl.report_id
            WHERE wr.tenant_id = :tenant_id 
              AND wr.user_id   = :user_id
            GROUP BY wr.id
            ORDER BY wr.week DESC
            LIMIT :limit
        ";

        try {
            $stmt = $this->pdo->prepare($sql);
            $stmt->bindValue(':tenant_id', $this->tenantId, PDO::PARAM_INT);
            $stmt->bindValue(':user_id',   $this->userId,   PDO::PARAM_INT);
            $stmt->bindValue(':limit',     $limit,          PDO::PARAM_INT);
            $stmt->execute();

            $reports = $stmt->fetchAll(PDO::FETCH_ASSOC) ?: [];

            return $this->json([
                'success' => true,
                'data'    => $reports,
                'count'   => count($reports),
            ]);
        } catch (Exception $e) {
            error_log("WeeklyReportsController::getReportHistory error: " . $e->getMessage());

            return $this->json([
                'success' => false,
                'message' => 'Unable to fetch report history.',
            ], 500);
        }
    }

    /**
     * Stats for weekly-reports dashboard.
     */
    public function getUserStats()
    {
        $this->authCheck();

        try {
            $reportsSql = "
                SELECT 
                    COUNT(*) AS total_reports,
                    SUM(CASE WHEN status = 'submitted' THEN 1 ELSE 0 END) AS submitted_reports,
                    SUM(CASE WHEN status = 'approved'  THEN 1 ELSE 0 END) AS approved_reports
                FROM weekly_reports
                WHERE tenant_id = :tenant_id 
                  AND user_id   = :user_id
            ";

            $rs = $this->pdo->prepare($reportsSql);
            $rs->execute([
                ':tenant_id' => $this->tenantId,
                ':user_id'   => $this->userId,
            ]);
            $reportStats = $rs->fetch(PDO::FETCH_ASSOC) ?: [
                'total_reports'     => 0,
                'submitted_reports' => 0,
                'approved_reports'  => 0,
            ];

            $currentWeek = $this->getCurrentWeek();
            $currentSql  = "
                SELECT status 
                FROM weekly_reports 
                WHERE tenant_id = :tenant_id 
                  AND user_id   = :user_id 
                  AND week      = :week
                LIMIT 1
            ";

            $cr = $this->pdo->prepare($currentSql);
            $cr->execute([
                ':tenant_id' => $this->tenantId,
                ':user_id'   => $this->userId,
                ':week'      => $currentWeek,
            ]);
            $currentReport = $cr->fetch(PDO::FETCH_ASSOC) ?: [];

            $stats = [
                'reports' => [
                    'total'               => (int)($reportStats['total_reports']     ?? 0),
                    'submitted'           => (int)($reportStats['submitted_reports'] ?? 0),
                    'approved'            => (int)($reportStats['approved_reports']  ?? 0),
                    'current_week_status' => $currentReport['status'] ?? 'not_started',
                ],
                'current_week' => $currentWeek,
            ];

            return $this->json([
                'success' => true,
                'data'    => $stats,
            ]);
        } catch (Exception $e) {
            error_log("WeeklyReportsController::getUserStats error: " . $e->getMessage());

            return $this->json([
                'success' => false,
                'message' => 'Unable to fetch user statistics.',
            ], 500);
        }
    }

    /**
     * Helper: current ISO week as YYYY-WW.
     */
    protected function getCurrentWeek(): string
    {
        return date('Y-\WW'); // e.g. 2025-W41
    }

    /**
     * Helper: validate "YYYY-WW" format.
     */
    private function validateWeekFormat(string $week): bool
    {
        if (!preg_match('/^\d{4}-W\d{2}$/', $week)) {
            return false;
        }

        [$year, $weekPart] = explode('-W', $week);
        $weekNum = (int)$weekPart;

        return $weekNum >= 1 && $weekNum <= 53;
    }
}
