<?php
namespace Controllers\Parent;

use Core\Controller;
use Models\ParentModel;
use Models\Mark;
use Models\Attendance;
use Models\FeeInvoice;

class ParentController extends Controller {
    private array $parent;

    private function getParent(): array {
        if (!isset($this->parent)) {
            $this->parent = (new ParentModel())->getByUserId($this->currentUser()['id']) ?? [];
        }
        return $this->parent;
    }

    public function dashboard(): void {
        $this->requireRole('parent');
        $parent   = $this->getParent();
        $students = $parent ? (new ParentModel())->getStudents($parent['id']) : [];
        $this->view('parent/dashboard', compact('parent','students'));
    }

    public function studentDetail(string $id): void {
        $this->requireRole('parent');
        $parent = $this->getParent();
        $link = $this->db->fetch(
            "SELECT * FROM parent_student WHERE parent_id=? AND student_id=?",
            [$parent['id'], (int)$id]
        );
        if (!$link) { $this->redirect('parent/dashboard'); return; }

        $student = $this->db->fetch(
            "SELECT s.*, u.name, u.email, cl.name AS class_name, st.name AS stream_name
             FROM students s JOIN users u ON u.id=s.user_id
             LEFT JOIN streams st ON st.id=s.stream_id
             LEFT JOIN classes cl ON cl.id=st.class_id
             WHERE s.id=?", [(int)$id]
        );

        // All published exams grouped by term
        $exams = $this->db->fetchAll(
            "SELECT e.*, t.name AS term_name, ay.name AS year_name
             FROM exams e
             JOIN terms t ON t.id=e.term_id
             JOIN academic_years ay ON ay.id=t.academic_year_id
             JOIN students s ON s.school_id=e.school_id
             WHERE s.id=? AND e.is_published=1
             ORDER BY ay.name DESC, t.id DESC, e.id DESC", [(int)$id]
        );

        $recentMarks = $this->db->fetchAll(
            "SELECT m.*, sub.name AS subject_name, e.name AS exam_name, t.name AS term_name
             FROM marks m JOIN subjects sub ON sub.id=m.subject_id
             JOIN exams e ON e.id=m.exam_id
             JOIN terms t ON t.id=e.term_id
             WHERE m.student_id=? AND e.is_published=1
             ORDER BY e.id DESC, sub.name", [(int)$id]
        );

        $currentInvoice = $this->db->fetch(
            "SELECT fi.*, (fi.total_amount - fi.amount_paid) AS balance
             FROM fee_invoices fi JOIN terms t ON t.id=fi.term_id
             WHERE fi.student_id=? AND t.is_current=1 LIMIT 1", [(int)$id]
        );
        $summary = (new Attendance())->getStudentSummary((int)$id);
        $school  = $this->db->fetch("SELECT mpesa_paybill FROM schools WHERE id=?", [$this->schoolId()]);
        $mpesaPaybill = $school['mpesa_paybill'] ?? '';
        $this->view('parent/student-detail', compact('student','exams','recentMarks','currentInvoice','summary','mpesaPaybill'));
    }

    public function initiatePayment(string $id): void {
        $this->requireRole('parent');
        $parent = $this->getParent();
        $link   = $this->db->fetch("SELECT * FROM parent_student WHERE parent_id=? AND student_id=?", [$parent['id'], (int)$id]);
        if (!$link) { $this->redirect('parent/dashboard'); return; }

        $this->verifyCsrf();
        $phone  = preg_replace('/[^0-9+]/', '', $this->request->post('phone', ''));
        $amount = (float)$this->request->post('amount', 0);
        $invoiceId = (int)$this->request->post('invoice_id', 0);

        if (!$phone || $amount <= 0 || !$invoiceId) {
            $this->withError('Phone number and amount are required.');
            $this->redirect('parent/student/'.$id);
            return;
        }

        $student = $this->db->fetch("SELECT s.*, u.name FROM students s JOIN users u ON u.id=s.user_id WHERE s.id=?", [(int)$id]);
        $result  = (new \Services\MpesaService($this->schoolId()))->stkPush($phone, $amount, $invoiceId, $student['assessment_no'] ?? 'FEES');

        if ($result['success']) {
            $this->withSuccess($result['message']);
            // Store checkout_id in session for polling
            \Core\Session::set('stk_checkout_id', $result['checkout_id'] ?? '');
            \Core\Session::set('stk_invoice_id', $invoiceId);
        } else {
            $this->withError($result['message']);
        }
        $this->redirect('parent/student/'.$id);
    }

    public function paymentStatus(string $id): void {
        $this->requireRole('parent');
        $checkoutId = $this->request->get('checkout_id', '');
        $result = (new \Services\MpesaService($this->schoolId()))->checkStatus($checkoutId);
        header('Content-Type: application/json');
        echo json_encode($result);
        exit;
    }

    public function feeHistory(string $studentId): void {
        $this->requireRole('parent');
        $parent = $this->getParent();
        $link   = $this->db->fetch("SELECT * FROM parent_student WHERE parent_id=? AND student_id=?", [$parent['id'], (int)$studentId]);
        if (!$link) { $this->redirect('parent/dashboard'); return; }

        $student  = $this->db->fetch("SELECT s.*, u.name FROM students s JOIN users u ON u.id=s.user_id WHERE s.id=?", [(int)$studentId]);
        $invoices = $this->db->fetchAll(
            "SELECT fi.*, t.name AS term_name, ay.name AS year_name
             FROM fee_invoices fi
             JOIN terms t ON t.id=fi.term_id
             JOIN academic_years ay ON ay.id=t.academic_year_id
             WHERE fi.student_id=? ORDER BY fi.id DESC", [(int)$studentId]
        );
        $payments = $this->db->fetchAll(
            "SELECT p.*, t.name AS term_name, ay.name AS year_name
             FROM payments p
             JOIN fee_invoices fi ON fi.id=p.invoice_id
             JOIN terms t ON t.id=fi.term_id
             JOIN academic_years ay ON ay.id=t.academic_year_id
             WHERE fi.student_id=? ORDER BY p.payment_date DESC", [(int)$studentId]
        );
        $this->view('parent/fee_history', compact('student','invoices','payments'));
    }

    public function downloadResults(string $studentId, string $examId): void {
        $this->requireRole('parent');
        $parent = $this->getParent();
        $link = $this->db->fetch(
            "SELECT * FROM parent_student WHERE parent_id=? AND student_id=?",
            [$parent['id'], (int)$studentId]
        );
        if (!$link) { $this->redirect('parent/dashboard'); return; }

        $student = $this->db->fetch(
            "SELECT s.*, u.name, cl.name AS class_name, st.name AS stream_name
             FROM students s JOIN users u ON u.id=s.user_id
             LEFT JOIN streams st ON st.id=s.stream_id
             LEFT JOIN classes cl ON cl.id=st.class_id
             WHERE s.id=?", [(int)$studentId]
        );
        $exam = $this->db->fetch(
            "SELECT e.*, t.name AS term_name, ay.name AS year_name
             FROM exams e JOIN terms t ON t.id=e.term_id
             JOIN academic_years ay ON ay.id=t.academic_year_id
             WHERE e.id=? AND e.is_published=1", [(int)$examId]
        );
        if (!$exam) { $this->redirect('parent/student/'.$studentId); return; }

        $marks = $this->db->fetchAll(
            "SELECT m.*, sub.name AS subject_name
             FROM marks m JOIN subjects sub ON sub.id=m.subject_id
             WHERE m.student_id=? AND m.exam_id=?
             ORDER BY sub.name", [(int)$studentId, (int)$examId]
        );
        $school      = $this->db->fetch("SELECT * FROM schools WHERE id=?", [$this->schoolId()]);
        $attendance  = (new Attendance())->getStudentSummary((int)$studentId);
        $feeInvoice  = $this->db->fetch(
            "SELECT fi.*, (fi.total_amount + IFNULL(fi.opening_balance,0) - fi.amount_paid) AS balance
             FROM fee_invoices fi JOIN terms t ON t.id=fi.term_id
             WHERE fi.student_id=? AND t.id=?
             LIMIT 1", [(int)$studentId, $exam['term_id']]
        );
        $competencies = $this->db->fetchAll(
            "SELECT c.name, cr.rating FROM competency_ratings cr
             JOIN competencies c ON c.id=cr.competency_id
             WHERE cr.student_id=? AND cr.term_id=?",
            [(int)$studentId, $exam['term_id']]
        );
        $classTeacherRemark = null;
        $principalRemark    = null;
        $template           = $this->request->get('template', 'A');
        $classPosition      = null;
        $classTotal         = null;

        if ($template === 'B') {
            $streamId = $student['stream_id'] ?? 0;
            $allAvgs  = $this->db->fetchAll(
                "SELECT m.student_id, AVG(m.score/m.out_of*100) AS avg_pct
                 FROM marks m JOIN students s ON s.id=m.student_id
                 WHERE m.exam_id=? AND s.stream_id=?
                 GROUP BY m.student_id ORDER BY avg_pct DESC",
                [(int)$examId, $streamId]
            );
            $classTotal = count($allAvgs);
            foreach ($allAvgs as $pos => $row)
                if ($row['student_id'] == $studentId) { $classPosition = $pos + 1; break; }
        }

        $this->view('pdf/report-card', compact(
            'student','exam','marks','school','attendance',
            'feeInvoice','competencies','classTeacherRemark','principalRemark',
            'template','classPosition','classTotal'
        ), null);
    }
}
