<?php
use Core\Controller;
use Core\Auth;

/**
 * OrganizationController — Platform super-admin review of organization signups
 */
class OrganizationController extends Controller
{
    public function __construct()
    {
        parent::__construct();
        $this->requireSuperAdmin();
    }

    public function index(): void
    {
        $status = $this->getGet('status', '');
        $where = '';
        $params = [];
        if (in_array($status, ['pending', 'approved', 'rejected'], true)) {
            $where = 'WHERE o.status = ?';
            $params[] = $status;
        }

        $organizations = $this->dbQuery(
            "SELECT o.*, p.name AS plan_name,
                    (SELECT COUNT(*) FROM users u WHERE u.org_id = o.id) AS user_count,
                    (SELECT CONCAT(u2.first_name, ' ', u2.last_name) FROM users u2 WHERE u2.org_id = o.id AND u2.entity_type = 'org_user' ORDER BY u2.id ASC LIMIT 1) AS admin_name,
                    (SELECT u3.email FROM users u3 WHERE u3.org_id = o.id AND u3.entity_type = 'org_user' ORDER BY u3.id ASC LIMIT 1) AS admin_email
             FROM organizations o
             LEFT JOIN plans p ON o.plan_id = p.id
             $where
             ORDER BY (o.status = 'pending') DESC, o.created_at DESC",
            $params
        );

        $counts = $this->dbQueryOne(
            "SELECT
                SUM(status = 'pending') AS pending,
                SUM(status = 'approved') AS approved,
                SUM(status = 'rejected') AS rejected,
                COUNT(*) AS total
             FROM organizations"
        );

        $this->render('organizations/index', [
            'pageTitle'     => 'Organizations',
            'organizations' => $organizations,
            'counts'        => $counts,
            'currentStatus' => $status,
        ]);
    }

    public function show($id): void
    {
        $org = $this->dbQueryOne(
            "SELECT o.*, p.name AS plan_name FROM organizations o LEFT JOIN plans p ON o.plan_id = p.id WHERE o.id = ?",
            [(int)$id]
        );
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $adminUser = $this->dbQueryOne(
            "SELECT * FROM users WHERE org_id = ? AND entity_type = 'org_user' ORDER BY id ASC LIMIT 1",
            [(int)$id]
        );

        $counts = $this->dbQueryOne(
            "SELECT
                (SELECT COUNT(*) FROM users WHERE org_id = ?) AS users,
                (SELECT COUNT(*) FROM projects WHERE org_id = ?) AS projects,
                (SELECT COUNT(*) FROM clients WHERE org_id = ?) AS clients,
                (SELECT COUNT(*) FROM contractors WHERE org_id = ?) AS contractors,
                (SELECT COUNT(*) FROM suppliers WHERE org_id = ?) AS suppliers,
                (SELECT COUNT(*) FROM invoices WHERE org_id = ?) AS invoices",
            [(int)$id, (int)$id, (int)$id, (int)$id, (int)$id, (int)$id]
        );

        $this->render('organizations/show', [
            'pageTitle' => $org['name'],
            'org'       => $org,
            'adminUser' => $adminUser,
            'counts'    => $counts,
        ]);
    }

    public function edit($id): void
    {
        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $plans = $this->dbQuery("SELECT id, name FROM plans WHERE is_active = 1 ORDER BY price ASC");

        $this->render('organizations/edit', [
            'pageTitle' => 'Edit ' . $org['name'],
            'org'       => $org,
            'plans'     => $plans,
        ]);
    }

    public function update($id): void
    {
        if (!$this->validateCsrf()) {
            $this->setFlash('error', 'Invalid security token.');
            $this->redirect('/admin/organizations/' . $id . '/edit');
        }

        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $name = trim($this->getPost('name', ''));
        if (empty($name)) {
            $this->setFlash('error', 'Organization name is required.');
            $this->redirect('/admin/organizations/' . $id . '/edit');
        }

        $planId = $this->getPost('plan_id', '');
        $data = [
            'name'                 => $name,
            'industry'             => trim($this->getPost('industry', '')) ?: null,
            'email'                => trim($this->getPost('email', '')) ?: null,
            'phone'                => trim($this->getPost('phone', '')) ?: null,
            'address'              => trim($this->getPost('address', '')) ?: null,
            'plan_id'              => $planId !== '' ? (int)$planId : null,
            'subscription_status'  => in_array($this->getPost('subscription_status', ''), ['active', 'trial', 'suspended'], true)
                                        ? $this->getPost('subscription_status')
                                        : $org['subscription_status'],
        ];

        $this->dbExecute(
            "UPDATE organizations SET name = ?, industry = ?, email = ?, phone = ?, address = ?, plan_id = ?, subscription_status = ? WHERE id = ?",
            [...array_values($data), (int)$id]
        );

        logAudit('organization_updated', 'organizations', 'organization', (int)$id, $org, $data);
        $this->setFlash('success', 'Organization updated.');
        $this->redirect('/admin/organizations/' . $id);
    }

    public function suspend($id): void
    {
        if (!$this->validateCsrf()) {
            $this->setFlash('error', 'Invalid security token.');
            $this->redirect('/admin/organizations');
        }

        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $this->dbExecute(
            "UPDATE organizations SET is_active = 0, subscription_status = 'suspended' WHERE id = ?",
            [(int)$id]
        );
        $this->dbExecute("UPDATE users SET is_active = 0 WHERE org_id = ?", [(int)$id]);

        logAudit('organization_suspended', 'organizations', 'organization', (int)$id);
        $this->setFlash('success', 'Organization suspended. All its users have been signed out of access.');
        $this->redirect('/admin/organizations/' . $id);
    }

    public function reactivate($id): void
    {
        if (!$this->validateCsrf()) {
            $this->setFlash('error', 'Invalid security token.');
            $this->redirect('/admin/organizations');
        }

        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $this->dbExecute(
            "UPDATE organizations SET is_active = 1, subscription_status = 'active' WHERE id = ?",
            [(int)$id]
        );
        $this->dbExecute(
            "UPDATE users SET is_active = 1 WHERE org_id = ? AND entity_type = 'org_user'",
            [(int)$id]
        );

        logAudit('organization_reactivated', 'organizations', 'organization', (int)$id);
        $this->setFlash('success', 'Organization reactivated.');
        $this->redirect('/admin/organizations/' . $id);
    }

    public function delete($id): void
    {
        if (!$this->validateCsrf()) {
            $this->setFlash('error', 'Invalid security token.');
            $this->redirect('/admin/organizations');
        }

        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        if ((int)$org['is_active'] === 1) {
            $this->setFlash('error', 'Suspend this organization before deleting it.');
            $this->redirect('/admin/organizations/' . $id);
        }

        logAudit('organization_deleted', 'organizations', 'organization', (int)$id, $org, null);
        $this->dbExecute("DELETE FROM organizations WHERE id = ?", [(int)$id]);

        $this->setFlash('success', 'Organization and all its data have been permanently deleted.');
        $this->redirect('/admin/organizations');
    }

    public function approve($id): void
    {
        if (!$this->validateCsrf()) {
            $this->setFlash('error', 'Invalid security token.');
            $this->redirect('/admin/organizations');
        }

        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $this->dbExecute(
            "UPDATE organizations SET status = 'approved', is_active = 1, approved_at = NOW() WHERE id = ?",
            [(int)$id]
        );

        $adminUser = $this->dbQueryOne(
            "SELECT * FROM users WHERE org_id = ? AND entity_type = 'org_user' ORDER BY id ASC LIMIT 1",
            [(int)$id]
        );

        if ($adminUser) {
            $this->dbExecute("UPDATE users SET is_active = 1 WHERE id = ?", [$adminUser['id']]);

            $adminRole = $this->dbQueryOne("SELECT id FROM roles WHERE name = 'admin' AND is_system = 1");
            if ($adminRole) {
                $hasRole = $this->dbQueryOne(
                    "SELECT id FROM user_roles WHERE user_id = ? AND role_id = ?",
                    [$adminUser['id'], $adminRole['id']]
                );
                if (!$hasRole) {
                    $this->dbExecute(
                        "INSERT INTO user_roles (user_id, role_id) VALUES (?, ?)",
                        [$adminUser['id'], $adminRole['id']]
                    );
                }
            }

            createNotification(
                (int)$adminUser['id'],
                'organization_approved',
                'Your organization has been approved',
                $org['name'] . ' is now active. You can sign in and get started.'
            );

            $htmlBody = $this->renderEmailTemplate('org_approved', [
                'userName' => $adminUser['first_name'],
                'orgName'  => $org['name'],
                'loginUrl' => APP_URL . '/login',
            ]);
            sendEmail(
                $adminUser['email'],
                $adminUser['first_name'] . ' ' . $adminUser['last_name'],
                'Your ' . APP_NAME . ' organization has been approved',
                $htmlBody
            );
        }

        logAudit('organization_approved', 'organizations', 'organization', (int)$id);
        $this->setFlash('success', 'Organization approved.');
        $this->redirect('/admin/organizations');
    }

    public function reject($id): void
    {
        if (!$this->validateCsrf()) {
            $this->setFlash('error', 'Invalid security token.');
            $this->redirect('/admin/organizations');
        }

        $org = $this->dbQueryOne("SELECT * FROM organizations WHERE id = ?", [(int)$id]);
        if (!$org) {
            $this->setFlash('error', 'Organization not found.');
            $this->redirect('/admin/organizations');
        }

        $this->dbExecute(
            "UPDATE organizations SET status = 'rejected', is_active = 0 WHERE id = ?",
            [(int)$id]
        );

        $adminUser = $this->dbQueryOne(
            "SELECT * FROM users WHERE org_id = ? AND entity_type = 'org_user' ORDER BY id ASC LIMIT 1",
            [(int)$id]
        );
        if ($adminUser) {
            $this->dbExecute("UPDATE users SET is_active = 0 WHERE id = ?", [$adminUser['id']]);
        }

        logAudit('organization_rejected', 'organizations', 'organization', (int)$id);
        $this->setFlash('success', 'Organization rejected.');
        $this->redirect('/admin/organizations');
    }

    private function renderEmailTemplate(string $template, array $data): string
    {
        extract($data);
        ob_start();
        $templatePath = ROOT_PATH . '/modules/auth/views/email_templates/' . $template . '.php';
        if (file_exists($templatePath)) {
            include $templatePath;
        }
        return ob_get_clean();
    }
}
