<?php
declare(strict_types=1);

namespace App\Modules\Members\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Archive\Services\ArchiveService;

class MemberArchiveController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();

        $filters = [
            'search'    => trim((string) $request->get('q', '')),
            'status'    => $request->get('status', ''),
            'date_from' => $request->get('date_from', ''),
            'date_to'   => $request->get('date_to', ''),
            'number'    => trim((string) $request->get('number', '')),
            'nid'       => trim((string) $request->get('nid', '')),
            'phone'     => trim((string) $request->get('phone', '')),
            'operator'  => trim((string) $request->get('operator', '')),
        ];

        $where = ['m.is_archived = 1'];
        $params = [];

        if ($filters['search'] !== '') {
            $where[] = "(m.full_name_ar LIKE ? OR m.full_name_en LIKE ?)";
            $params[] = '%' . $filters['search'] . '%';
            $params[] = '%' . $filters['search'] . '%';
        }
        if ($filters['status'] !== '') {
            $where[] = "m.status = ?";
            $params[] = $filters['status'];
        }
        if ($filters['date_from'] !== '') {
            $where[] = "m.archived_at >= ?";
            $params[] = $filters['date_from'] . ' 00:00:00';
        }
        if ($filters['date_to'] !== '') {
            $where[] = "m.archived_at <= ?";
            $params[] = $filters['date_to'] . ' 23:59:59';
        }
        if ($filters['number'] !== '') {
            $where[] = "(m.membership_number = ? OR EXISTS (SELECT 1 FROM archive_snapshots sa WHERE sa.entity_type = 'members' AND sa.entity_id = m.id AND sa.membership_number = ?))";
            $params[] = $filters['number'];
            $params[] = $filters['number'];
        }
        if ($filters['nid'] !== '') {
            $where[] = "m.national_id LIKE ?";
            $params[] = '%' . $filters['nid'] . '%';
        }
        if ($filters['phone'] !== '') {
            $where[] = "(m.phone_mobile LIKE ? OR m.phone_home LIKE ?)";
            $params[] = '%' . $filters['phone'] . '%';
            $params[] = '%' . $filters['phone'] . '%';
        }
        if ($filters['operator'] !== '') {
            $where[] = "e.full_name_ar LIKE ?";
            $params[] = '%' . $filters['operator'] . '%';
        }

        $whereClause = implode(' AND ', $where);

        $page = max(1, (int) $request->get('page', 1));
        $perPage = 25;
        $offset = ($page - 1) * $perPage;

        $countSql = "SELECT COUNT(*) as total FROM members m
                     LEFT JOIN employees e ON e.id = m.archived_by
                     WHERE {$whereClause}";
        $total = (int) ($db->selectOne($countSql, $params)['total'] ?? 0);

        $sql = "SELECT m.id, m.full_name_ar, m.national_id, m.phone_mobile, m.membership_type, m.status,
                       m.archived_at, m.archived_by,
                       (SELECT sa.membership_number FROM archive_snapshots sa WHERE sa.entity_type = 'members' AND sa.entity_id = m.id ORDER BY sa.snapshot_taken_at DESC LIMIT 1) as archived_membership_number,
                       (SELECT sa.snapshot_reason FROM archive_snapshots sa WHERE sa.entity_type = 'members' AND sa.entity_id = m.id ORDER BY sa.snapshot_taken_at DESC LIMIT 1) as snapshot_reason,
                       (SELECT sa.id FROM archive_snapshots sa WHERE sa.entity_type = 'members' AND sa.entity_id = m.id ORDER BY sa.snapshot_taken_at DESC LIMIT 1) as snapshot_id,
                       e.full_name_ar as operator_name
                FROM members m
                LEFT JOIN employees e ON e.id = m.archived_by
                WHERE {$whereClause}
                ORDER BY m.archived_at DESC
                LIMIT {$perPage} OFFSET {$offset}";
        $rows = $db->select($sql, $params);

        $lastPage = max(1, (int) ceil($total / $perPage));
        $pagination = [
            'current_page' => $page,
            'last_page'    => $lastPage,
            'total'        => $total,
            'has_prev'     => $page > 1,
            'has_next'     => $page < $lastPage,
            'prev_page'    => $page - 1,
            'next_page'    => $page + 1,
            'pages'        => self::paginateRange($page, $lastPage),
        ];

        return $this->view('Members.Views.archive_index', [
            'rows'       => $rows,
            'pagination' => $pagination,
            'filters'    => $filters,
            'total'      => $total,
        ]);
    }

    public function show(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $member = $db->selectOne("SELECT * FROM members WHERE id = ? AND is_archived = 1", [(int) $id]);
        if (!$member) return $this->redirect('/members/archive')->withError('العضو المؤرشف غير موجود');

        // Get all snapshots for this member
        $snapshots = $db->select(
            "SELECT * FROM archive_snapshots WHERE entity_type = 'members' AND entity_id = ? ORDER BY snapshot_taken_at DESC",
            [(int) $id]
        );

        // Primary snapshot (most recent)
        $primarySnapshot = null;
        if (!empty($snapshots)) {
            $primarySnapshot = ArchiveService::getSnapshot((int) $snapshots[0]['id']);
        }

        // Get number chain if membership number exists in snapshot
        $numberChain = [];
        $membershipNumber = $primarySnapshot['membership_number'] ?? null;
        if ($membershipNumber) {
            $numberChain = ArchiveService::getNumberChain($membershipNumber);
        }

        // Get linked new member (who received the number)
        $linkedMember = null;
        if ($membershipNumber) {
            $currentHolder = ArchiveService::getCurrentHolder($membershipNumber);
            if ($currentHolder && (int) $currentHolder['holder_entity_id'] !== (int) $id) {
                $linkedMember = $db->selectOne(
                    "SELECT id, full_name_ar, membership_number, status FROM members WHERE id = ?",
                    [(int) $currentHolder['holder_entity_id']]
                );
            }
        }

        // Get audit trail for this member
        $auditTrail = $db->select(
            "SELECT * FROM audit_trail WHERE entity_type = 'members' AND entity_id = ? ORDER BY created_at DESC LIMIT 50",
            [(int) $id]
        );

        // Dependents from snapshot related_data or live data
        $dependents = [
            'spouses'   => $db->select("SELECT * FROM spouses WHERE member_id = ?", [(int) $id]),
            'children'  => $db->select("SELECT * FROM children WHERE member_id = ?", [(int) $id]),
            'temporary' => $db->select("SELECT * FROM temporary_members WHERE member_id = ?", [(int) $id]),
        ];

        // Operator info
        $operator = null;
        if ($member['archived_by']) {
            $operator = $db->selectOne("SELECT id, full_name_ar FROM employees WHERE id = ?", [(int) $member['archived_by']]);
        }

        return $this->view('Members.Views.archive_show', [
            'member'           => $member,
            'snapshots'        => $snapshots,
            'primarySnapshot'  => $primarySnapshot,
            'numberChain'      => $numberChain,
            'linkedMember'     => $linkedMember,
            'auditTrail'       => $auditTrail,
            'dependents'       => $dependents,
            'operator'         => $operator,
            'membershipNumber' => $membershipNumber,
        ]);
    }

    private static function paginateRange(int $current, int $last): array
    {
        if ($last <= 7) return range(1, $last);
        $pages = [1];
        $start = max(2, $current - 2);
        $end = min($last - 1, $current + 2);
        if ($start > 2) $pages[] = '...';
        for ($i = $start; $i <= $end; $i++) $pages[] = $i;
        if ($end < $last - 1) $pages[] = '...';
        $pages[] = $last;
        return $pages;
    }
}
