<?hh // strict

namespace App\Controllers;

use App\Services\AuthService;
use Firebase\JWT\JWT;
use Firebase\JWT\Key;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class AuthController
{
    private AuthService $authService;
    
    public function __construct()
    {
        $this->authService = new AuthService();
    }

    public function login(Request $request, Response $response): Response
    {
        // For traditional login, you would validate credentials here
        // For OIDC/social login, redirect to appropriate provider
        
        $params = $request->getParsedBody();
        $provider = $params['provider'] ?? null;
        
        switch ($provider) {
            case 'google':
                $authUrl = $this->authService->getGoogleAuthorizationUrl();
                $response->getBody()->write(json_encode(['redirect_url' => $authUrl]));
                break;
            case 'github':
                $authUrl = $this->authService->getGithubAuthorizationUrl();
                $response->getBody()->write(json_encode(['redirect_url' => $authUrl]));
                break;
            default:
                // Traditional login
                $email = $params['email'] ?? '';
                $password = $params['password'] ?? '';
                
                // Validate credentials (simplified)
                if ($this->validateCredentials($email, $password)) {
                    $token = $this->generateToken($email);
                    $response->getBody()->write(json_encode(['token' => $token, 'message' => 'Login successful']));
                } else {
                    $response = $response->withStatus(401);
                    $response->getBody()->write(json_encode(['error' => 'Invalid credentials']));
                }
                break;
        }
        
        return $response->withHeader('Content-Type', 'application/json');
    }

    public function logout(Request $request, Response $response): Response
    {
        // Clear any tokens, sessions, etc.
        $response->getBody()->write(json_encode(['message' => 'Logout successful']));
        return $response->withHeader('Content-Type', 'application/json');
    }

    public function register(Request $request, Response $response): Response
    {
        $params = $request->getParsedBody();
        $email = $params['email'] ?? '';
        $name = $params['name'] ?? '';
        $password = $params['password'] ?? '';
        
        // Validate input
        if (empty($email) || empty($name) || empty($password)) {
            $response = $response->withStatus(400);
            $response->getBody()->write(json_encode(['error' => 'All fields are required']));
            return $response->withHeader('Content-Type', 'application/json');
        }
        
        // Register user (simplified)
        if ($this->registerUser($email, $name, $password)) {
            $token = $this->generateToken($email);
            $response->getBody()->write(json_encode(['token' => $token, 'message' => 'Registration successful']));
        } else {
            $response = $response->withStatus(500);
            $response->getBody()->write(json_encode(['error' => 'Registration failed']));
        }
        
        return $response->withHeader('Content-Type', 'application/json');
    }
    
    public function googleCallback(Request $request, Response $response): Response
    {
        try {
            $userData = $this->authService->handleGoogleCallback($request);
            
            // Check if user exists, create if not
            $user = $this->findOrCreateUser($userData);
            
            // Generate JWT token
            $token = $this->generateToken($user['email']);
            
            // Redirect to frontend with token
            $redirectUrl = $_ENV['FRONTEND_URL'] ?? 'http://localhost:3000' . "/auth/callback?token={$token}";
            return $response->withHeader('Location', $redirectUrl)->withStatus(302);
        } catch (\Exception $e) {
            $response = $response->withStatus(500);
            $response->getBody()->write(json_encode(['error' => $e->getMessage()]));
            return $response->withHeader('Content-Type', 'application/json');
        }
    }
    
    public function githubCallback(Request $request, Response $response): Response
    {
        try {
            $userData = $this->authService->handleGithubCallback($request);
            
            // Check if user exists, create if not
            $user = $this->findOrCreateUser($userData);
            
            // Generate JWT token
            $token = $this->generateToken($user['email']);
            
            // Redirect to frontend with token
            $redirectUrl = $_ENV['FRONTEND_URL'] ?? 'http://localhost:3000' . "/auth/callback?token={$token}";
            return $response->withHeader('Location', $redirectUrl)->withStatus(302);
        } catch (\Exception $e) {
            $response = $response->withStatus(500);
            $response->getBody()->write(json_encode(['error' => $e->getMessage()]));
            return $response->withHeader('Content-Type', 'application/json');
        }
    }
    
    private function validateCredentials(string $email, string $password): bool
    {
        // This would normally check against a database
        // For now, just return true for demo purposes
        return !empty($email) && !empty($password);
    }
    
    private function registerUser(string $email, string $name, string $password): bool
    {
        // This would normally store the user in a database
        // For now, just return true for demo purposes
        return true;
    }
    
    private function findOrCreateUser(array $userData): array
    {
        // This would normally query the database to find or create a user
        // For now, return mock user data
        return [
            'id' => 1,
            'email' => $userData['email'],
            'name' => $userData['name'],
        ];
    }
    
    private function generateToken(string $email): string
    {
        $payload = [
            'iss' => 'MerchantsOfHope', // Issuer
            'sub' => $email,            // Subject
            'iat' => time(),            // Issued at
            'exp' => time() + 3600      // Expiration time (1 hour)
        ];
        
        return JWT::encode($payload, $_ENV['JWT_SECRET'], 'HS256');
    }
}