<?php
class MeetingController extends Controller
{
    public function index(Request $request): void
    {
        $this->view('meetings/index', [
            'title' => lang('board.meetings'),
            'breadcrumbs' => [
                ['label' => lang('board.module'), 'url' => '/board/terms'],
                ['label' => lang('board.meetings')]
            ],
        ]);
    }

    public function datatable(Request $request): void
    {
        $db = $this->db();
        $draw = (int) $request->get('draw', 1);
        $start = (int) $request->get('start', 0);
        $length = (int) $request->get('length', 25);
        $search = $request->get('search')['value'] ?? '';

        $where = '1=1';
        $params = [];
        if ($search) {
            $where .= " AND (m.meeting_number LIKE ? OR m.title_en LIKE ? OR m.title_ar LIKE ?)";
            $params = array_merge($params, ["%{$search}%", "%{$search}%", "%{$search}%"]);
        }

        $total = (int) $db->fetchColumn("SELECT COUNT(*) FROM board_meetings");
        $filtered = (int) $db->fetchColumn("SELECT COUNT(*) FROM board_meetings m WHERE {$where}", $params);

        $rows = $db->fetchAll(
            "SELECT m.*, bt.term_name_en FROM board_meetings m
             LEFT JOIN board_terms bt ON m.term_id = bt.id
             WHERE {$where} ORDER BY m.meeting_date DESC LIMIT {$length} OFFSET {$start}",
            $params
        );

        $data = [];
        foreach ($rows as $row) {
            $actions = '<a href="/board/meetings/' . $row['id'] . '" class="btn btn-sm btn-outline-primary me-1"><i class="fas fa-eye"></i></a>';
            if (auth_can('board.manage')) {
                $actions .= '<a href="/board/meetings/' . $row['id'] . '/edit" class="btn btn-sm btn-outline-warning me-1"><i class="fas fa-edit"></i></a>';
            }

            $data[] = [
                'id' => $row['id'],
                'number' => e($row['meeting_number']),
                'title' => e(current_lang() === 'ar' ? ($row['title_ar'] ?: $row['title_en']) : $row['title_en']),
                'type' => status_badge($row['meeting_type']),
                'date' => format_date($row['meeting_date']),
                'status' => status_badge($row['status']),
                'quorum' => $row['quorum_met'] ? '<i class="fas fa-check text-success"></i>' : '<i class="fas fa-times text-danger"></i>',
                'attendees' => $row['attendees_count'],
                'actions' => $actions,
            ];
        }

        $this->json(['draw' => $draw, 'recordsTotal' => $total, 'recordsFiltered' => $filtered, 'data' => $data]);
    }

    public function create(Request $request): void
    {
        $terms = $this->db()->fetchAll("SELECT id, term_name_en, term_name_ar FROM board_terms WHERE status IN ('upcoming','active') ORDER BY start_date DESC");
        $committees = $this->db()->fetchAll("SELECT id, name_en, name_ar FROM board_committees WHERE is_active = 1 ORDER BY name_en");

        $this->view('meetings/form', [
            'title' => lang('board.create_meeting'),
            'breadcrumbs' => [
                ['label' => lang('board.module'), 'url' => '/board/terms'],
                ['label' => lang('board.meetings'), 'url' => '/board/meetings'],
                ['label' => lang('common.create')]
            ],
            'meeting' => null,
            'terms' => $terms,
            'committees' => $committees,
            'agendaItems' => [],
            'formAction' => '/board/meetings',
        ]);
    }

    public function store(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid token'], 403);
            return;
        }

        $validator = new Validator($request->all(), [
            'term_id'          => 'required|integer|exists:board_terms,id',
            'committee_id'     => 'nullable|integer',
            'meeting_type'     => 'required|in:regular,emergency,special,annual_general',
            'title_en'         => 'required|string|max:300',
            'title_ar'         => 'nullable|string|max:300',
            'meeting_date'     => 'required|date',
            'start_time'       => 'nullable|string|max:8',
            'end_time'         => 'nullable|string|max:8',
            'location'         => 'nullable|string|max:300',
            'quorum_required'  => 'required|integer|min:0',
            'notes'            => 'nullable|string|max:5000',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $meetingNumber = SequenceGenerator::next('meeting_number');
        $data['meeting_number'] = $meetingNumber ?: 'MTG-' . str_pad(rand(1, 99999), 5, '0', STR_PAD_LEFT);
        $data['status'] = 'scheduled';
        $data['created_by'] = auth_id();

        $id = $this->db()->insert('board_meetings', $data);

        // Insert agenda items
        $agendaTitles = $request->post('agenda_title', []);
        $agendaDescs = $request->post('agenda_description', []);
        if (is_array($agendaTitles)) {
            foreach ($agendaTitles as $idx => $title) {
                if (empty(trim($title))) continue;
                $this->db()->insert('board_meeting_agenda', [
                    'meeting_id' => $id,
                    'agenda_number' => $idx + 1,
                    'title_en' => $title,
                    'description' => $agendaDescs[$idx] ?? null,
                    'sort_order' => $idx + 1,
                    'status' => 'pending',
                ]);
            }
        }

        $this->audit('create', 'board_meetings', $id, 'Created meeting: ' . $data['meeting_number']);
        $this->json(['success' => true, 'message' => lang('board.meeting_created'), 'redirect' => '/board/meetings/' . $id]);
    }

    public function show(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $db = $this->db();

        $meeting = $db->fetchOne(
            "SELECT m.*, bt.term_name_en, bt.term_name_ar, bc.name_en as committee_name
             FROM board_meetings m
             LEFT JOIN board_terms bt ON m.term_id = bt.id
             LEFT JOIN board_committees bc ON m.committee_id = bc.id
             WHERE m.id = ?", [$id]
        );
        if (!$meeting) { $this->abort(404); return; }

        $agendaItems = $db->fetchAll("SELECT * FROM board_meeting_agenda WHERE meeting_id = ? ORDER BY sort_order", [$id]);
        $attendees = $db->fetchAll(
            "SELECT bma.*, bm.full_name_en, bm.full_name_ar, bp.title_en as position_title
             FROM board_meeting_attendees bma
             JOIN board_members bm ON bma.board_member_id = bm.id
             LEFT JOIN board_positions bp ON bm.position_id = bp.id
             WHERE bma.meeting_id = ?
             ORDER BY bp.sort_order", [$id]
        );
        $boardMembers = $db->fetchAll(
            "SELECT bm.id, bm.full_name_en, bm.full_name_ar, bp.title_en as position_title
             FROM board_members bm
             LEFT JOIN board_positions bp ON bm.position_id = bp.id
             WHERE bm.term_id = ? AND bm.status = 'active'
             ORDER BY bp.sort_order", [$meeting['term_id']]
        );
        $resolutions = $db->fetchAll("SELECT * FROM board_resolutions WHERE meeting_id = ? ORDER BY resolution_number", [$id]);

        $this->view('meetings/show', [
            'title' => e($meeting['meeting_number']),
            'breadcrumbs' => [
                ['label' => lang('board.module'), 'url' => '/board/terms'],
                ['label' => lang('board.meetings'), 'url' => '/board/meetings'],
                ['label' => e($meeting['meeting_number'])]
            ],
            'meeting' => $meeting,
            'agendaItems' => $agendaItems,
            'attendees' => $attendees,
            'boardMembers' => $boardMembers,
            'resolutions' => $resolutions,
        ]);
    }

    public function edit(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $meeting = $this->db()->fetchOne("SELECT * FROM board_meetings WHERE id = ?", [$id]);
        if (!$meeting) { $this->abort(404); return; }

        $terms = $this->db()->fetchAll("SELECT id, term_name_en, term_name_ar FROM board_terms ORDER BY start_date DESC");
        $committees = $this->db()->fetchAll("SELECT id, name_en, name_ar FROM board_committees WHERE is_active = 1");
        $agendaItems = $this->db()->fetchAll("SELECT * FROM board_meeting_agenda WHERE meeting_id = ? ORDER BY sort_order", [$id]);

        $this->view('meetings/form', [
            'title' => lang('board.edit_meeting'),
            'breadcrumbs' => [
                ['label' => lang('board.module'), 'url' => '/board/terms'],
                ['label' => lang('board.meetings'), 'url' => '/board/meetings'],
                ['label' => lang('common.edit')]
            ],
            'meeting' => $meeting,
            'terms' => $terms,
            'committees' => $committees,
            'agendaItems' => $agendaItems,
            'formAction' => '/board/meetings/' . $id,
        ]);
    }

    public function update(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid token'], 403);
            return;
        }

        $old = $this->db()->fetchOne("SELECT * FROM board_meetings WHERE id = ?", [$id]);
        if (!$old) { $this->json(['success' => false, 'message' => 'Not found'], 404); return; }

        $validator = new Validator($request->all(), [
            'term_id'          => 'required|integer',
            'committee_id'     => 'nullable|integer',
            'meeting_type'     => 'required|in:regular,emergency,special,annual_general',
            'title_en'         => 'required|string|max:300',
            'title_ar'         => 'nullable|string|max:300',
            'meeting_date'     => 'required|date',
            'start_time'       => 'nullable|string|max:8',
            'end_time'         => 'nullable|string|max:8',
            'location'         => 'nullable|string|max:300',
            'quorum_required'  => 'required|integer|min:0',
            'minutes_text'     => 'nullable|string',
            'notes'            => 'nullable|string|max:5000',
        ]);

        if ($validator->fails()) {
            $this->json(['success' => false, 'errors' => $validator->errors()], 422);
            return;
        }

        $data = $validator->validated();
        $this->db()->update('board_meetings', $data, 'id = ?', [$id]);

        // Re-save agenda
        $this->db()->delete('board_meeting_agenda', 'meeting_id = ?', [$id]);
        $agendaTitles = $request->post('agenda_title', []);
        $agendaDescs = $request->post('agenda_description', []);
        if (is_array($agendaTitles)) {
            foreach ($agendaTitles as $idx => $title) {
                if (empty(trim($title))) continue;
                $this->db()->insert('board_meeting_agenda', [
                    'meeting_id' => $id,
                    'agenda_number' => $idx + 1,
                    'title_en' => $title,
                    'description' => $agendaDescs[$idx] ?? null,
                    'sort_order' => $idx + 1,
                    'status' => 'pending',
                ]);
            }
        }

        $this->audit('update', 'board_meetings', $id, 'Updated meeting: ' . $old['meeting_number'], $old, $data);
        $this->json(['success' => true, 'message' => lang('board.meeting_updated'), 'redirect' => '/board/meetings/' . $id]);
    }

    public function saveAttendance(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid token'], 403);
            return;
        }

        $meeting = $this->db()->fetchOne("SELECT * FROM board_meetings WHERE id = ?", [$id]);
        if (!$meeting) { $this->json(['success' => false, 'message' => 'Not found'], 404); return; }

        $attendanceData = $request->post('attendance', []);
        $this->db()->delete('board_meeting_attendees', 'meeting_id = ?', [$id]);

        $presentCount = 0;
        foreach ($attendanceData as $bmId => $status) {
            if (empty($status)) continue;
            $this->db()->insert('board_meeting_attendees', [
                'meeting_id' => $id,
                'board_member_id' => (int) $bmId,
                'attendance' => $status,
            ]);
            if (in_array($status, ['present', 'proxy'])) {
                $presentCount++;
            }
        }

        $quorumMet = $presentCount >= $meeting['quorum_required'] ? 1 : 0;
        $this->db()->update('board_meetings', [
            'attendees_count' => $presentCount,
            'quorum_met' => $quorumMet,
        ], 'id = ?', [$id]);

        $this->audit('update', 'board_meetings', $id, "Recorded attendance: {$presentCount} present, quorum " . ($quorumMet ? 'met' : 'NOT met'));
        $this->json(['success' => true, 'message' => lang('board.attendance_saved')]);
    }

    public function approveMinutes(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid token'], 403);
            return;
        }

        $this->db()->update('board_meetings', [
            'minutes_approved' => 1,
            'minutes_approved_at' => date('Y-m-d H:i:s'),
        ], 'id = ?', [$id]);

        $this->audit('approve', 'board_meetings', $id, 'Approved meeting minutes');
        $this->json(['success' => true, 'message' => lang('board.minutes_approved')]);
    }

    public function changeStatus(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        if (!CSRF::validate($request->csrfToken())) {
            $this->json(['success' => false, 'message' => 'Invalid token'], 403);
            return;
        }

        $newStatus = $request->post('status', '');
        $valid = ['scheduled', 'in_progress', 'completed', 'cancelled', 'postponed'];
        if (!in_array($newStatus, $valid)) {
            $this->json(['success' => false, 'message' => 'Invalid status'], 400);
            return;
        }

        $this->db()->update('board_meetings', ['status' => $newStatus], 'id = ?', [$id]);
        $this->audit('update', 'board_meetings', $id, "Changed meeting status to: {$newStatus}");
        $this->json(['success' => true, 'message' => lang('board.status_updated')]);
    }
}