<?php

class FreezeApiController extends Controller
{
    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'] ?? '';
        $status = $request->get('status', '');

        $where  = "1=1";
        $params = [];

        if ($status !== '') { $where .= " AND mf.status = ?"; $params[] = $status; }
        if ($search !== '') {
            $where .= " AND (m.membership_number LIKE ? OR m.full_name_en LIKE ? OR mf.freeze_number LIKE ?)";
            $s = "%{$search}%"; $params = array_merge($params, [$s, $s, $s]);
        }

        $total = (int) $db->fetchColumn("SELECT COUNT(*) FROM member_freezes mf JOIN members m ON mf.member_id = m.id WHERE {$where}", $params);

        $rows = $db->fetchAll(
            "SELECT mf.id, mf.freeze_number, mf.freeze_reason, mf.start_date, mf.original_end_date, mf.actual_end_date,
                    mf.duration_days, mf.status, mf.fee_amount, mf.fee_paid,
                    m.membership_number, m.full_name_en AS member_name
             FROM member_freezes mf JOIN members m ON mf.member_id = m.id
             WHERE {$where} ORDER BY mf.created_at DESC LIMIT {$length} OFFSET {$start}",
            $params
        );

        $data = [];
        foreach ($rows as $r) {
            $actions = '<a href="/freezes/' . $r['id'] . '" class="btn btn-sm btn-outline-primary"><i class="fas fa-eye"></i></a>';
            if ($r['status'] === 'pending' && Gate::can('freezes.approve')) {
                $actions .= ' <button class="btn btn-sm btn-outline-success btn-approve-freeze" data-id="' . $r['id'] . '"><i class="fas fa-check"></i></button>';
                $actions .= ' <button class="btn btn-sm btn-outline-danger btn-reject-freeze" data-id="' . $r['id'] . '"><i class="fas fa-times"></i></button>';
            }
            $data[] = [
                'freeze_number'     => e($r['freeze_number']),
                'membership_number' => e($r['membership_number']),
                'member_name'       => e($r['member_name']),
                'reason'            => str_limit(e($r['freeze_reason']), 40),
                'start_date'        => format_date($r['start_date']),
                'end_date'          => format_date($r['actual_end_date'] ?? $r['original_end_date']),
                'duration'          => $r['duration_days'] . ' days',
                'fee'               => format_money($r['fee_amount']),
                'status'            => status_badge($r['status']),
                'actions'           => $actions,
            ];
        }

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

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

        $v = new Validator($request->all(), [
            'member_id'       => 'required|integer|exists:members,id',
            'freeze_reason'   => 'required|string|max:500',
            'reason_category' => 'nullable|string|max:50',
            'start_date'      => 'required|date',
            'end_date'        => 'required|date',
        ]);
        if ($v->fails()) { $this->json(['success' => false, 'errors' => $v->errors()], 422); return; }

        $d  = $v->validated();
        $db = $this->db();

        try {
            $db->execute(
                "CALL sp_create_freeze(?, ?, ?, ?, ?, ?, @freeze_id, @result)",
                [$d['member_id'], $d['freeze_reason'], $d['reason_category'] ?? 'general', $d['start_date'], $d['end_date'], Auth::id()]
            );
            $result = $db->fetchOne("SELECT @freeze_id AS id, @result AS msg");

            if ($result['id']) {
                $this->audit('create', 'member_freezes', (int)$result['id'], $result['msg']);
                $this->json(['success' => true, 'message' => $result['msg'], 'redirect' => '/freezes/' . $result['id']]);
            } else {
                $this->json(['success' => false, 'message' => $result['msg']], 422);
            }
        } catch (\Exception $e) {
            Logger::error('Freeze creation failed: ' . $e->getMessage());
            $this->json(['success' => false, 'message' => 'Failed to create freeze request'], 500);
        }
    }

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

        $id = (int) $request->routeParam('id');
        $db = $this->db();
        $freeze = $db->fetchOne("SELECT id, status, member_id, start_date FROM member_freezes WHERE id = ?", [$id]);

        if (!$freeze || $freeze['status'] !== 'pending') {
            $this->json(['success' => false, 'message' => 'Freeze not pending'], 422); return;
        }

        $newStatus = ($freeze['start_date'] <= date('Y-m-d')) ? 'active' : 'approved';

        $db->update('member_freezes', [
            'status'      => $newStatus,
            'approved_by' => Auth::id(),
            'approved_at' => date('Y-m-d H:i:s'),
            'activated_at' => $newStatus === 'active' ? date('Y-m-d H:i:s') : null,
            'updated_at'  => date('Y-m-d H:i:s'),
        ], 'id = ?', [$id]);

        $this->audit('approve', 'member_freezes', $id, "Freeze approved → {$newStatus}");
        $this->json(['success' => true, 'message' => 'Freeze approved']);
    }

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

        $id = (int) $request->routeParam('id');
        $reason = $request->post('rejection_reason', '');
        $db = $this->db();

        $freeze = $db->fetchOne("SELECT id, status FROM member_freezes WHERE id = ?", [$id]);
        if (!$freeze || $freeze['status'] !== 'pending') {
            $this->json(['success' => false, 'message' => 'Freeze not pending'], 422); return;
        }

        $db->update('member_freezes', [
            'status'           => 'rejected',
            'rejection_reason' => $reason,
            'updated_at'       => date('Y-m-d H:i:s'),
        ], 'id = ?', [$id]);

        $this->audit('reject', 'member_freezes', $id, 'Freeze rejected: ' . $reason);
        $this->json(['success' => true, 'message' => 'Freeze rejected']);
    }

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

        $id = (int) $request->routeParam('id');
        $reason = $request->post('reason', 'Early termination');
        $db = $this->db();

        $freeze = $db->fetchOne("SELECT id, status, member_id FROM member_freezes WHERE id = ?", [$id]);
        if (!$freeze || !in_array($freeze['status'], ['active', 'approved'])) {
            $this->json(['success' => false, 'message' => 'Freeze cannot be ended'], 422); return;
        }

        $db->update('member_freezes', [
            'status'          => 'ended',
            'actual_end_date' => date('Y-m-d'),
            'ended_at'        => date('Y-m-d H:i:s'),
            'ended_by'        => Auth::id(),
            'early_end_reason' => $reason,
            'updated_at'      => date('Y-m-d H:i:s'),
        ], 'id = ?', [$id]);

        // Restore member status
        $db->update('members', [
            'status'            => 'active',
            'status_reason'     => 'Freeze ended early',
            'status_changed_at' => date('Y-m-d H:i:s'),
            'status_changed_by' => Auth::id(),
        ], "id = ? AND status = 'frozen'", [$freeze['member_id']]);

        $this->audit('update', 'member_freezes', $id, 'Freeze ended early: ' . $reason);
        $this->json(['success' => true, 'message' => 'Freeze ended successfully']);
    }

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

        $id = (int) $request->routeParam('id');
        $v = new Validator($request->all(), [
            'extension_days' => 'required|integer|min:1|max:365',
            'reason'         => 'required|string|max:500',
        ]);
        if ($v->fails()) { $this->json(['success' => false, 'errors' => $v->errors()], 422); return; }

        $d = $v->validated();
        $db = $this->db();

        $freeze = $db->fetchOne("SELECT * FROM member_freezes WHERE id = ? AND status IN ('active','approved')", [$id]);
        if (!$freeze) { $this->json(['success' => false, 'message' => 'Freeze not found or cannot be extended'], 422); return; }

        $currentEnd = $freeze['actual_end_date'] ?? $freeze['original_end_date'];
        $newEnd = date('Y-m-d', strtotime($currentEnd . ' + ' . $d['extension_days'] . ' days'));

        $extId = $db->insert('freeze_extensions', [
            'freeze_id'      => $id,
            'extension_days' => $d['extension_days'],
            'new_end_date'   => $newEnd,
            'reason'         => $d['reason'],
            'additional_fee' => 0,
            'status'         => 'approved',
            'approved_by'    => Auth::id(),
            'approved_at'    => date('Y-m-d H:i:s'),
            'created_by'     => Auth::id(),
        ]);

        $db->update('member_freezes', [
            'actual_end_date' => $newEnd,
            'duration_days'   => $freeze['duration_days'] + $d['extension_days'],
            'extension_days'  => ($freeze['extension_days'] ?? 0) + $d['extension_days'],
            'updated_at'      => date('Y-m-d H:i:s'),
        ], 'id = ?', [$id]);

        $this->audit('update', 'member_freezes', $id, "Extended by {$d['extension_days']} days to {$newEnd}");
        $this->json(['success' => true, 'message' => "Freeze extended to {$newEnd}"]);
    }

    // ── POLICIES ──
    public function policiesDatatable(Request $request): void
    {
        $rows = $this->db()->fetchAll(
            "SELECT fp.*, mt.name_en AS type_name
             FROM freeze_policies fp LEFT JOIN membership_types mt ON fp.membership_type_id = mt.id
             ORDER BY fp.policy_code"
        );
        $data = [];
        foreach ($rows as $r) {
            $data[] = [
                'id'          => $r['id'],
                'policy_code' => e($r['policy_code']),
                'name_en'     => e($r['name_en']),
                'name_ar'     => e($r['name_ar']),
                'type_name'   => $r['type_name'] ? e($r['type_name']) : '<em>All Types</em>',
                'max_days'    => $r['max_days'] ?? '∞',
                'max_times'   => $r['max_times_per_year'] ?? '∞',
                'fee_type'    => e($r['fee_type']),
                'fee_amount'  => format_money($r['fee_amount']),
                'is_active'   => $r['is_active'] ? '<span class="badge bg-success">Active</span>' : '<span class="badge bg-secondary">Inactive</span>',
                'actions'     => '<button class="btn btn-sm btn-outline-warning btn-edit-policy" data-id="' . $r['id'] . '"><i class="fas fa-edit"></i></button>',
            ];
        }
        $this->json(['draw' => 1, 'recordsTotal' => count($data), 'recordsFiltered' => count($data), 'data' => $data]);
    }

    public function getPolicy(Request $request): void
    {
        $id = (int) $request->routeParam('id');
        $row = $this->db()->fetchOne("SELECT * FROM freeze_policies WHERE id = ?", [$id]);
        $this->json($row ? ['success' => true, 'data' => $row] : ['success' => false], $row ? 200 : 404);
    }

    public function storePolicy(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) { $this->json(['success' => false, 'message' => 'CSRF'], 403); return; }
        $v = new Validator($request->all(), [
            'policy_code' => 'required|string|max:30', 'name_en' => 'required|string|max:200', 'name_ar' => 'required|string|max:200',
            'membership_type_id' => 'nullable|integer', 'min_days' => 'required|integer|min:1', 'max_days' => 'nullable|integer',
            'max_times_per_year' => 'nullable|integer', 'max_total_days_per_year' => 'nullable|integer',
            'fee_type' => 'required|in:none,fixed,per_day,percentage_of_subscription', 'fee_amount' => 'required|decimal',
            'requires_approval' => 'nullable|boolean', 'extend_subscription' => 'nullable|boolean', 'is_active' => 'nullable|boolean',
        ]);
        if ($v->fails()) { $this->json(['success' => false, 'errors' => $v->errors()], 422); return; }
        $d = $v->validated();
        $d['requires_approval'] = $d['requires_approval'] ?? 0;
        $d['extend_subscription'] = $d['extend_subscription'] ?? 1;
        $d['is_active'] = $d['is_active'] ?? 1;
        if (empty($d['membership_type_id'])) $d['membership_type_id'] = null;

        $id = $this->db()->insert('freeze_policies', $d);
        $this->audit('create', 'freeze_policies', $id, 'Created freeze policy: ' . $d['policy_code']);
        $this->json(['success' => true, 'message' => 'Policy created']);
    }

    public function updatePolicy(Request $request): void
    {
        if (!CSRF::validate($request->csrfToken())) { $this->json(['success' => false, 'message' => 'CSRF'], 403); return; }
        $id = (int) $request->routeParam('id');
        $v = new Validator($request->all(), [
            'policy_code' => 'required|string|max:30', 'name_en' => 'required|string|max:200', 'name_ar' => 'required|string|max:200',
            'membership_type_id' => 'nullable|integer', 'min_days' => 'required|integer|min:1', 'max_days' => 'nullable|integer',
            'max_times_per_year' => 'nullable|integer', 'max_total_days_per_year' => 'nullable|integer',
            'fee_type' => 'required|in:none,fixed,per_day,percentage_of_subscription', 'fee_amount' => 'required|decimal',
            'requires_approval' => 'nullable|boolean', 'extend_subscription' => 'nullable|boolean', 'is_active' => 'nullable|boolean',
        ]);
        if ($v->fails()) { $this->json(['success' => false, 'errors' => $v->errors()], 422); return; }
        $d = $v->validated();
        $d['requires_approval'] = $d['requires_approval'] ?? 0;
        $d['extend_subscription'] = $d['extend_subscription'] ?? 1;
        $d['is_active'] = $d['is_active'] ?? 0;
        if (empty($d['membership_type_id'])) $d['membership_type_id'] = null;

        $this->db()->update('freeze_policies', $d, 'id = ?', [$id]);
        $this->audit('update', 'freeze_policies', $id, 'Updated freeze policy');
        $this->json(['success' => true, 'message' => 'Policy updated']);
    }
}