<?php
class AccessController extends Controller
{
    public function points(Request $request): void
    {
        $db = $this->db();
        $points = $db->fetchAll(
            "SELECT ap.*, f.name_en AS facility_name_en, f.name_ar AS facility_name_ar
             FROM access_points ap
             LEFT JOIN facilities f ON ap.facility_id = f.id
             ORDER BY ap.name_en"
        );
        $facilities = $db->fetchAll("SELECT id, name_en, name_ar FROM facilities WHERE is_active = 1 ORDER BY name_en");

        $this->view('access/points', [
            'title'       => lang('cards.access_points'),
            'breadcrumbs' => [
                ['label' => lang('cards.access_control'), 'url' => '/access/log'],
                ['label' => lang('cards.access_points')],
            ],
            'points'     => $points,
            'facilities' => $facilities,
        ]);
    }

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

        $validator = new Validator($request->all(), [
            'point_code'    => 'required|string|max:20',
            'name_en'       => 'required|string|max:200',
            'name_ar'       => 'required|string|max:200',
            'location'      => 'nullable|string|max:300',
            'facility_id'   => 'nullable|integer',
            'point_type'    => 'required|in:main_gate,facility_entrance,parking,pool,gym,court,other',
            'hardware_type' => 'required|in:turnstile,gate,door,barrier,scanner,manual',
            'direction'     => 'required|in:entry,exit,both',
        ]);

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

        $data = $validator->validated();
        $data['is_active'] = 1;

        $id = $this->db()->insert('access_points', $data);
        $this->audit('create', 'access_points', $id, "Access point created: {$data['name_en']}");

        $this->json(['success' => true, 'message' => lang('common.save') . ' ✓']);
    }

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

        $id = (int)$request->routeParam('id');

        $validator = new Validator($request->all(), [
            'name_en'       => 'required|string|max:200',
            'name_ar'       => 'required|string|max:200',
            'location'      => 'nullable|string|max:300',
            'facility_id'   => 'nullable|integer',
            'point_type'    => 'required|in:main_gate,facility_entrance,parking,pool,gym,court,other',
            'hardware_type' => 'required|in:turnstile,gate,door,barrier,scanner,manual',
            'direction'     => 'required|in:entry,exit,both',
            'is_active'     => 'nullable|in:0,1',
        ]);

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

        $data = $validator->validated();
        $data['is_active'] = $data['is_active'] ?? 1;
        $db = $this->db();
        $old = $db->fetchOne("SELECT * FROM access_points WHERE id = ?", [$id]);
        $db->update('access_points', $data, 'id = ?', [$id]);
        $this->audit('update', 'access_points', $id, "Access point updated", $old, $data);

        $this->json(['success' => true, 'message' => lang('common.save') . ' ✓']);
    }

    public function rules(Request $request): void
    {
        $db = $this->db();
        $rules = $db->fetchAll(
            "SELECT acr.*, ap.name_en AS point_name_en, ap.name_ar AS point_name_ar,
                    mt.name_en AS memtype_name_en, mt.name_ar AS memtype_name_ar
             FROM access_control_rules acr
             JOIN access_points ap ON acr.access_point_id = ap.id
             LEFT JOIN membership_types mt ON acr.membership_type_id = mt.id
             ORDER BY acr.priority DESC, acr.id"
        );
        $points = $db->fetchAll("SELECT id, name_en, name_ar FROM access_points WHERE is_active = 1 ORDER BY name_en");
        $membershipTypes = $db->fetchAll("SELECT id, name_en, name_ar FROM membership_types WHERE is_active = 1 ORDER BY sort_order");

        $this->view('access/rules', [
            'title'       => lang('cards.access_rules'),
            'breadcrumbs' => [
                ['label' => lang('cards.access_control'), 'url' => '/access/log'],
                ['label' => lang('cards.access_rules')],
            ],
            'rules'           => $rules,
            'points'          => $points,
            'membershipTypes' => $membershipTypes,
        ]);
    }

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

        $validator = new Validator($request->all(), [
            'access_point_id'        => 'required|integer|exists:access_points,id',
            'rule_name'              => 'required|string|max:200',
            'membership_type_id'     => 'nullable|integer',
            'member_status_required' => 'required|string|max:50',
            'subscription_required'  => 'nullable|in:0,1',
            'card_required'          => 'nullable|in:0,1',
            'allow_dependents'       => 'nullable|in:0,1',
            'allow_guests'           => 'nullable|in:0,1',
            'max_daily_entries'      => 'nullable|integer|min:1',
            'priority'               => 'nullable|integer|min:0',
        ]);

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

        $data = $validator->validated();
        $data['subscription_required'] = $data['subscription_required'] ?? 1;
        $data['card_required']         = $data['card_required'] ?? 1;
        $data['allow_dependents']      = $data['allow_dependents'] ?? 1;
        $data['allow_guests']          = $data['allow_guests'] ?? 0;
        $data['priority']              = $data['priority'] ?? 0;
        $data['is_active']             = 1;

        $id = $this->db()->insert('access_control_rules', $data);
        $this->audit('create', 'access_control_rules', $id, "Access rule created: {$data['rule_name']}");

        $this->json(['success' => true, 'message' => lang('common.save') . ' ✓']);
    }

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

        $id = (int)$request->routeParam('id');
        $validator = new Validator($request->all(), [
            'rule_name'              => 'required|string|max:200',
            'membership_type_id'     => 'nullable|integer',
            'member_status_required' => 'required|string|max:50',
            'subscription_required'  => 'nullable|in:0,1',
            'card_required'          => 'nullable|in:0,1',
            'allow_dependents'       => 'nullable|in:0,1',
            'allow_guests'           => 'nullable|in:0,1',
            'max_daily_entries'      => 'nullable|integer|min:1',
            'priority'               => 'nullable|integer|min:0',
            'is_active'              => 'nullable|in:0,1',
        ]);

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

        $data = $validator->validated();
        $data['subscription_required'] = $data['subscription_required'] ?? 1;
        $data['card_required']         = $data['card_required'] ?? 1;
        $data['allow_dependents']      = $data['allow_dependents'] ?? 1;
        $data['allow_guests']          = $data['allow_guests'] ?? 0;
        $data['is_active']             = $data['is_active'] ?? 1;

        $db = $this->db();
        $old = $db->fetchOne("SELECT * FROM access_control_rules WHERE id = ?", [$id]);
        $db->update('access_control_rules', $data, 'id = ?', [$id]);
        $this->audit('update', 'access_control_rules', $id, "Access rule updated", $old, $data);

        $this->json(['success' => true, 'message' => lang('common.save') . ' ✓']);
    }

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

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

        $db->delete('access_control_rules', 'id = ?', [$id]);
        $this->audit('delete', 'access_control_rules', $id, "Access rule deleted: {$old['rule_name']}", $old);

        $this->json(['success' => true, 'message' => lang('common.delete') . ' ✓']);
    }

    public function log(Request $request): void
    {
        $db = $this->db();
        $todayEntries = (int)$db->fetchColumn("SELECT COUNT(*) FROM member_access_log WHERE DATE(access_time) = CURDATE() AND direction = 'entry' AND granted = 1");
        $todayDenied  = (int)$db->fetchColumn("SELECT COUNT(*) FROM member_access_log WHERE DATE(access_time) = CURDATE() AND granted = 0");
        $todayExits   = (int)$db->fetchColumn("SELECT COUNT(*) FROM member_access_log WHERE DATE(access_time) = CURDATE() AND direction = 'exit' AND granted = 1");

        $this->view('access/log', [
            'title'       => lang('cards.access_log'),
            'breadcrumbs' => [
                ['label' => lang('cards.access_control'), 'url' => '/access/log'],
                ['label' => lang('cards.access_log')],
            ],
            'todayEntries' => $todayEntries,
            'todayDenied'  => $todayDenied,
            'todayExits'   => $todayExits,
        ]);
    }
}