<?php
/**
 * Admin Controller (Platform Admin only)
 */

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Support\Database;
use App\Support\Response;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

class AdminController
{
    private array $config;
    
    public function __construct(array $config)
    {
        $this->config = $config;
    }
    
    /**
     * GET /api/admin/tenants
     */
    public function listTenants(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $page = (int)($request->getQueryParams()['page'] ?? 1);
        $limit = min((int)($request->getQueryParams()['limit'] ?? 20), 100);
        $offset = ($page - 1) * $limit;
        $status = $request->getQueryParams()['status'] ?? null;
        
        $where = '';
        $params = [];
        
        if ($status) {
            $where = 'WHERE status = $1';
            $params[] = $status;
        }
        
        $total = Database::fetch("SELECT COUNT(*) as count FROM tenants {$where}", $params)['count'];
        
        $tenants = Database::fetchAll(
            "SELECT id, name, slug, email, status, trial_ends_at, is_self_hosted, created_at 
             FROM tenants {$where} 
             ORDER BY created_at DESC 
             LIMIT {$limit} OFFSET {$offset}",
            $params
        );
        
        // Get module counts
        foreach ($tenants as &$tenant) {
            $modules = Database::fetchAll(
                'SELECT m.key FROM modules m JOIN tenant_modules tm ON tm.module_id = m.id WHERE tm.tenant_id = $1 AND tm.status = $2',
                [$tenant['id'], 'enabled']
            );
            $tenant['modules'] = array_column($modules, 'key');
            $tenant['module_count'] = count($modules);
        }
        
        return Response::success($response, [
            'tenants' => $tenants,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => (int)$total,
                'pages' => ceil($total / $limit),
            ],
        ]);
    }
    
    /**
     * POST /api/admin/tenants
     */
    public function createTenant(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $body = $request->getParsedBody();
        
        $name = trim($body['name'] ?? '');
        $email = trim($body['email'] ?? '');
        $phone = trim($body['phone'] ?? '');
        $address = trim($body['address'] ?? '');
        
        $errors = [];
        if (empty($name)) $errors['name'] = 'Name is required';
        if (empty($email)) $errors['email'] = 'Email is required';
        
        if (!empty($errors)) {
            return Response::validationError($response, $errors);
        }
        
        $slug = strtolower(preg_replace('/[^a-z0-9]+/', '-', $name));
        $originalSlug = $slug;
        $counter = 1;
        while (Database::fetch('SELECT id FROM tenants WHERE slug = $1', [$slug])) {
            $slug = $originalSlug . '-' . $counter++;
        }
        
        $tenantId = Database::insert('tenants', [
            'name' => $name,
            'slug' => $slug,
            'email' => $email,
            'phone' => $phone,
            'address' => $address,
            'status' => 'active',
        ]);
        
        $tenant = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$tenantId]);
        
        return Response::success($response, $tenant, 'Tenant created', 201);
    }
    
    /**
     * GET /api/admin/tenants/:id
     */
    public function getTenant(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $tenant = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        
        if (!$tenant) {
            return Response::notFound($response, 'Tenant not found');
        }
        
        // Get branches
        $tenant['branches'] = Database::fetchAll(
            'SELECT * FROM branches WHERE tenant_id = $1 ORDER BY is_headquarters DESC, name ASC',
            [$id]
        );
        
        // Get users count
        $tenant['user_count'] = Database::fetch(
            'SELECT COUNT(*) as count FROM users WHERE tenant_id = $1',
            [$id]
        )['count'];
        
        // Get modules
        $modules = Database::fetchAll(
            'SELECT m.*, tm.status, tm.enabled_at FROM modules m JOIN tenant_modules tm ON tm.module_id = m.id WHERE tm.tenant_id = $1',
            [$id]
        );
        $tenant['modules'] = $modules;
        
        return Response::success($response, $tenant);
    }
    
    /**
     * PUT /api/admin/tenants/:id
     */
    public function updateTenant(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        $body = $request->getParsedBody();
        
        $tenant = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        if (!$tenant) {
            return Response::notFound($response, 'Tenant not found');
        }
        
        $allowed = ['name', 'email', 'phone', 'address', 'status', 'primary_color', 'secondary_color', 'logo_url', 'custom_css'];
        $data = array_intersect_key($body, array_flip($allowed));
        
        if (!empty($data)) {
            Database::update('tenants', $data, 'id = $1', [$id]);
        }
        
        $updated = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        
        return Response::success($response, $updated, 'Tenant updated');
    }
    
    /**
     * DELETE /api/admin/tenants/:id
     */
    public function deleteTenant(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $tenant = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        if (!$tenant) {
            return Response::notFound($response, 'Tenant not found');
        }
        
        // Check if tenant has users
        $userCount = Database::fetch('SELECT COUNT(*) as count FROM users WHERE tenant_id = $1', [$id])['count'];
        if ($userCount > 0) {
            return Response::error($response, 'Cannot delete tenant with users. Delete users first.', 400);
        }
        
        Database::delete('tenants', 'id = $1', [$id]);
        
        return Response::success($response, null, 'Tenant deleted');
    }
    
    /**
     * POST /api/admin/tenants/:id/approve
     */
    public function approveTenant(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $tenant = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        if (!$tenant) {
            return Response::notFound($response, 'Tenant not found');
        }
        
        if ($tenant['status'] !== 'pending_approval') {
            return Response::error($response, 'Tenant is not pending approval', 400);
        }
        
        // Set to trial for 14 days
        $trialEnds = date('Y-m-d H:i:s', strtotime('+14 days'));
        
        Database::update('tenants', [
            'status' => 'trial',
            'trial_ends_at' => $trialEnds,
        ], 'id = $1', [$id]);
        
        $updated = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        
        return Response::success($response, $updated, 'Tenant approved, trial started');
    }
    
    /**
     * POST /api/admin/tenants/:id/suspend
     */
    public function suspendTenant(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $tenant = Database::fetch('SELECT * FROM tenants WHERE id = $1', [$id]);
        if (!$tenant) {
            return Response::notFound($response, 'Tenant not found');
        }
        
        Database::update('tenants', ['status' => 'suspended'], 'id = $1', [$id]);
        
        return Response::success($response, null, 'Tenant suspended');
    }
    
    /**
     * GET /api/admin/tenants/:id/modules
     */
    public function getTenantModules(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $modules = Database::fetchAll(
            'SELECT m.*, tm.status, tm.enabled_at, tm.expires_at, tm.trial_ends_at 
             FROM modules m 
             LEFT JOIN tenant_modules tm ON tm.module_id = m.id AND tm.tenant_id = $1 
             ORDER BY m.name',
            [$id]
        );
        
        return Response::success($response, $modules);
    }
    
    /**
     * POST /api/admin/tenants/:id/modules
     */
    public function enableTenantModule(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        $body = $request->getParsedBody();
        
        $moduleId = $body['module_id'] ?? '';
        $expiresAt = $body['expires_at'] ?? null;
        $trialEndsAt = $body['trial_ends_at'] ?? null;
        
        if (empty($moduleId)) {
            return Response::validationError($response, ['module_id' => 'Module ID is required']);
        }
        
        // Check if module exists
        $module = Database::fetch('SELECT * FROM modules WHERE id = $1', [$moduleId]);
        if (!$module) {
            return Response::notFound($response, 'Module not found');
        }
        
        // Check if already enabled
        $existing = Database::fetch(
            'SELECT * FROM tenant_modules WHERE tenant_id = $1 AND module_id = $2',
            [$id, $moduleId]
        );
        
        if ($existing) {
            return Response::error($response, 'Module already enabled for this tenant', 409);
        }
        
        Database::insert('tenant_modules', [
            'tenant_id' => $id,
            'module_id' => $moduleId,
            'status' => 'enabled',
            'expires_at' => $expiresAt,
            'trial_ends_at' => $trialEndsAt,
        ]);
        
        return Response::success($response, null, 'Module enabled', 201);
    }
    
    /**
     * DELETE /api/admin/tenants/:id/modules/:moduleId
     */
    public function disableTenantModule(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $tenantId = $args['id'];
        $moduleId = $args['moduleId'];
        
        Database::delete('tenant_modules', 'tenant_id = $1 AND module_id = $2', [$tenantId, $moduleId]);
        
        return Response::success($response, null, 'Module disabled');
    }
    
    /**
     * GET /api/admin/platform-modules
     */
    public function listPlatformModules(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $modules = Database::fetchAll('SELECT * FROM modules ORDER BY name');
        
        return Response::success($response, $modules);
    }
    
    /**
     * GET /api/admin/audit-logs
     */
    public function listAuditLogs(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $page = (int)($request->getQueryParams()['page'] ?? 1);
        $limit = min((int)($request->getQueryParams()['limit'] ?? 50), 100);
        $offset = ($page - 1) * $limit;
        
        $tenantId = $request->getQueryParams()['tenant_id'] ?? null;
        $action = $request->getQueryParams()['action'] ?? null;
        $entityType = $request->getQueryParams()['entity_type'] ?? null;
        
        $where = [];
        $params = [];
        $paramIndex = 1;
        
        if ($tenantId) {
            $where[] = "tenant_id = \${$paramIndex}";
            $params[] = $tenantId;
            $paramIndex++;
        }
        
        if ($action) {
            $where[] = "action = \${$paramIndex}";
            $params[] = $action;
            $paramIndex++;
        }
        
        if ($entityType) {
            $where[] = "entity_type = \${$paramIndex}";
            $params[] = $entityType;
            $paramIndex++;
        }
        
        $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
        
        $total = Database::fetch("SELECT COUNT(*) as count FROM audit_logs {$whereClause}", $params)['count'];
        
        $logs = Database::fetchAll(
            "SELECT al.*, 
                    pa.name as admin_name, pa.email as admin_email,
                    u.first_name, u.last_name, u.email as user_email,
                    t.name as tenant_name
             FROM audit_logs al
             LEFT JOIN platform_admins pa ON al.user_id = al.tenant_id IS NULL AND pa.id = al.user_id
             LEFT JOIN users u ON al.tenant_id IS NOT NULL AND u.id = al.user_id
             LEFT JOIN tenants t ON t.id = al.tenant_id
             {$whereClause}
             ORDER BY al.created_at DESC
             LIMIT {$limit} OFFSET {$offset}",
            $params
        );
        
        return Response::success($response, [
            'logs' => $logs,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => (int)$total,
                'pages' => ceil($total / $limit),
            ],
        ]);
    }
    
    /**
     * GET /api/admin/invoices
     */
    public function listInvoices(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $page = (int)($request->getQueryParams()['page'] ?? 1);
        $limit = min((int)($request->getQueryParams()['limit'] ?? 20), 100);
        $offset = ($page - 1) * $limit;
        $status = $request->getQueryParams()['status'] ?? null;
        
        $tenantId = $request->getQueryParams()['tenant_id'] ?? null;
        
        $where = [];
        $params = [];
        $paramIndex = 1;
        
        if ($status) {
            $where[] = "i.status = \${$paramIndex}";
            $params[] = $status;
            $paramIndex++;
        }
        
        if ($tenantId) {
            $where[] = "i.tenant_id = \${$paramIndex}";
            $params[] = $tenantId;
            $paramIndex++;
        }
        
        $whereClause = !empty($where) ? 'WHERE ' . implode(' AND ', $where) : '';
        
        $total = Database::fetch("SELECT COUNT(*) as count FROM invoices i {$whereClause}", $params)['count'];
        
        $invoices = Database::fetchAll(
            "SELECT i.*, t.name as tenant_name, t.slug as tenant_slug
             FROM invoices i
             JOIN tenants t ON t.id = i.tenant_id
             {$whereClause}
             ORDER BY i.created_at DESC
             LIMIT {$limit} OFFSET {$offset}",
            $params
        );
        
        return Response::success($response, [
            'invoices' => $invoices,
            'pagination' => [
                'page' => $page,
                'limit' => $limit,
                'total' => (int)$total,
                'pages' => ceil($total / $limit),
            ],
        ]);
    }
    
    /**
     * PUT /api/admin/invoices/:id/mark-paid
     */
    public function markInvoicePaid(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $invoice = Database::fetch('SELECT * FROM invoices WHERE id = $1', [$id]);
        if (!$invoice) {
            return Response::notFound($response, 'Invoice not found');
        }
        
        Database::update('invoices', [
            'status' => 'paid',
            'paid_at' => date('Y-m-d H:i:s'),
        ], 'id = $1', [$id]);
        
        $updated = Database::fetch('SELECT * FROM invoices WHERE id = $1', [$id]);
        
        return Response::success($response, $updated, 'Invoice marked as paid');
    }
    
    /**
     * GET /api/admin/platform-admins
     */
    public function listPlatformAdmins(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $admins = Database::fetchAll(
            'SELECT id, email, name, role, created_at, last_login_at FROM platform_admins ORDER BY created_at DESC'
        );
        
        return Response::success($response, $admins);
    }
    
    /**
     * POST /api/admin/platform-admins
     */
    public function createPlatformAdmin(ServerRequestInterface $request, ResponseInterface $response): ResponseInterface
    {
        $body = $request->getParsedBody();
        
        $email = trim($body['email'] ?? '');
        $name = trim($body['name'] ?? '');
        $password = $body['password'] ?? '';
        $role = $body['role'] ?? 'support';
        
        $errors = [];
        if (empty($email)) $errors['email'] = 'Email is required';
        if (empty($name)) $errors['name'] = 'Name is required';
        if (empty($password)) $errors['password'] = 'Password is required';
        elseif (strlen($password) < 8) $errors['password'] = 'Password must be at least 8 characters';
        
        if (!empty($errors)) {
            return Response::validationError($response, $errors);
        }
        
        // Check if email exists
        if (Database::fetch('SELECT id FROM platform_admins WHERE email = $1', [$email])) {
            return Response::error($response, 'Email already exists', 409);
        }
        
        $id = Database::insert('platform_admins', [
            'email' => $email,
            'name' => $name,
            'password_hash' => password_hash($password, PASSWORD_DEFAULT),
            'role' => $role,
        ]);
        
        $admin = Database::fetch(
            'SELECT id, email, name, role, created_at FROM platform_admins WHERE id = $1',
            [$id]
        );
        
        return Response::success($response, $admin, 'Platform admin created', 201);
    }
    
    /**
     * PUT /api/admin/platform-admins/:id
     */
    public function updatePlatformAdmin(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        $body = $request->getParsedBody();
        
        $allowed = ['name', 'role'];
        if (!empty($body['password'])) {
            $allowed[] = 'password_hash';
            $body['password_hash'] = password_hash($body['password'], PASSWORD_DEFAULT);
        }
        
        $data = array_intersect_key($body, array_flip($allowed));
        
        if (!empty($data)) {
            Database::update('platform_admins', $data, 'id = $1', [$id]);
        }
        
        $admin = Database::fetch(
            'SELECT id, email, name, role, created_at, last_login_at FROM platform_admins WHERE id = $1',
            [$id]
        );
        
        return Response::success($response, $admin, 'Platform admin updated');
    }
    
    /**
     * DELETE /api/admin/platform-admins/:id
     */
    public function deletePlatformAdmin(ServerRequestInterface $request, ResponseInterface $response, array $args): ResponseInterface
    {
        $id = $args['id'];
        
        $auth = $request->getAttribute('auth');
        if ($auth['id'] === $id) {
            return Response::error($response, 'Cannot delete yourself', 400);
        }
        
        Database::delete('platform_admins', 'id = $1', [$id]);
        
        return Response::success($response, null, 'Platform admin deleted');
    }
}