#!/usr/bin/env python3
"""
Simple HTTP server to serve the search demo page and handle CORS issues.
"""

import http.server
import socketserver
import urllib.request
import urllib.parse
import json
import sys
import ssl
from urllib.parse import urlparse, parse_qs

class CORSRequestHandler(http.server.SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
        self.send_header('Access-Control-Allow-Headers', 'Content-Type')
        super().end_headers()

    def do_GET(self):
        # Parse the URL
        parsed_path = urlparse(self.path)
        
        # Check if this is an API proxy request
        if parsed_path.path == '/api/search':
            self.handle_api_request(parsed_path.query)
        elif parsed_path.path == '/api/thumbnail':
            self.handle_thumbnail_request(parsed_path.query)
        elif parsed_path.path == '/api/check-url':
            self.handle_url_check_request(parsed_path.query)
        else:
            # Serve static files normally
            super().do_GET()
    
    def handle_api_request(self, query_string):
        try:
            print(f"Handling API request: {query_string}")
            
            # Parse query parameters
            params = parse_qs(query_string)
            print(f"Parsed params: {params}")
            
            # Build the API URL - using endpoint that supports enableContent
            api_base = 'https://searchapi.cloudsway.net/search/ynNUnbXHEuDGSGrj/smart'
            api_params = {
                'q': params.get('q', [''])[0],
                'count': params.get('count', ['10'])[0],
                'contentType': params.get('contentType', ['HTML'])[0]
            }
            
            # Add contentTimeout parameter if provided
            content_timeout = params.get('contentTimeout', [''])[0]
            if content_timeout:
                api_params['contentTimeout'] = content_timeout
            
            # Add freshness parameter if provided
            freshness = params.get('freshness', [''])[0]
            if freshness:
                api_params['freshness'] = freshness
            
            # Add offset parameter if provided
            offset = params.get('offset', [''])[0]
            if offset:
                api_params['offset'] = offset
            
            # Add enableContent parameter if provided
            enable_content = params.get('enableContent', [''])[0]
            if enable_content == 'true':
                print(f"Adding enableContent=true to API request")
                api_params['enableContent'] = 'true'
            
            # Add mainText parameter if provided
            main_text = params.get('mainText', [''])[0]
            if main_text == 'true':
                print(f"Adding mainText=true to API request")
                api_params['mainText'] = 'true'
            
            # Only add sites parameter if it's provided and not empty
            sites = params.get('sites', [''])[0]
            if sites and sites.strip():
                api_params['sites'] = sites
            
            # Always use GET request with URL parameters
            api_url = f"{api_base}?{urllib.parse.urlencode(api_params)}"
            print(f"Making GET request to: {api_url}")
            
            # Create request with headers
            request = urllib.request.Request(api_url)
            request.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36')
            request.add_header('Accept', 'application/json')
            request.add_header('Authorization', 'Bearer SN4iJJnVCW1EeQ6YLnQ2')
            
            # Create SSL context that doesn't verify certificates (for development only)
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE
            
            # Make the request to the actual API
            with urllib.request.urlopen(request, timeout=30, context=ssl_context) as response:
                data = response.read()
                print(f"API response status: {response.status}")
                
            # Send the response back to the client
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            self.wfile.write(data)
            
        except urllib.error.HTTPError as e:
            print(f"HTTP Error: {e.code} - {e.reason}")
            error_body = e.read().decode() if hasattr(e, 'read') else 'No response body'
            print(f"Response: {error_body}")
            
            # Check if this is the "endpoint does not support full functionality" error
            if e.code == 400 and 'enableContent' in api_params:
                try:
                    error_data = json.loads(error_body)
                    if error_data.get('error', {}).get('code') == '1227':
                        print("Endpoint doesn't support enableContent, trying without it...")
                        # Retry without enableContent
                        api_params_retry = api_params.copy()
                        del api_params_retry['enableContent']
                        
                        api_url_retry = f"{api_base}?{urllib.parse.urlencode(api_params_retry)}"
                        print(f"Retrying request to: {api_url_retry}")
                        
                        request_retry = urllib.request.Request(api_url_retry)
                        request_retry.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36')
                        request_retry.add_header('Accept', 'application/json')
                        request_retry.add_header('Authorization', 'Bearer SN4iJJnVCW1EeQ6YLnQ2')
                        
                        with urllib.request.urlopen(request_retry, timeout=30, context=ssl_context) as response:
                            data = response.read()
                            print(f"Retry API response status: {response.status}")
                            
                        # Send the response back to the client
                        self.send_response(200)
                        self.send_header('Content-Type', 'application/json')
                        self.end_headers()
                        self.wfile.write(data)
                        return
                except:
                    pass  # If retry fails, fall through to original error handling
            
            self.send_response(500)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            error_response = json.dumps({'error': f'API returned {e.code}: {e.reason}'})
            self.wfile.write(error_response.encode())
            
        except urllib.error.URLError as e:
            print(f"URL Error: {e.reason}")
            self.send_response(500)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            error_response = json.dumps({'error': f'Network error: {e.reason}'})
            self.wfile.write(error_response.encode())
            
        except Exception as e:
            print(f"Unexpected error: {type(e).__name__}: {str(e)}")
            import traceback
            traceback.print_exc()
            
            # Send error response
            self.send_response(500)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            error_response = json.dumps({'error': f'Server error: {str(e)}'})
            self.wfile.write(error_response.encode())
    
    def handle_thumbnail_request(self, query_string):
        try:
            # Parse query parameters
            params = parse_qs(query_string)
            thumbnail_url = params.get('url', [''])[0]
            
            if not thumbnail_url:
                self.send_response(400)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                error_response = json.dumps({'error': 'Missing thumbnail URL'})
                self.wfile.write(error_response.encode())
                return
            
            print(f"Proxying thumbnail: {thumbnail_url}")
            
            # Check if the URL looks valid
            if not thumbnail_url.startswith(('http://', 'https://')):
                print(f"Invalid thumbnail URL format: {thumbnail_url}")
                raise Exception("Invalid URL format")
            
            # Create request for thumbnail
            request = urllib.request.Request(thumbnail_url)
            request.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36')
            request.add_header('Referer', 'https://www.youtube.com/')
            
            # Create SSL context that doesn't verify certificates
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE
            
            # Make the request
            with urllib.request.urlopen(request, timeout=10, context=ssl_context) as response:
                image_data = response.read()
                content_type = response.headers.get('Content-Type', 'image/jpeg')
                
            # Send the image back to the client
            self.send_response(200)
            self.send_header('Content-Type', content_type)
            self.send_header('Cache-Control', 'public, max-age=3600')
            self.end_headers()
            self.wfile.write(image_data)
            
        except Exception as e:
            print(f"Thumbnail proxy error for URL {thumbnail_url}: {type(e).__name__}: {str(e)}")
            import traceback
            traceback.print_exc()
            
            # Send a 1x1 transparent pixel as fallback
            self.send_response(200)
            self.send_header('Content-Type', 'image/png')
            self.end_headers()
            # 1x1 transparent PNG
            transparent_pixel = b'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x01\x00\x00\x00\x01\x08\x06\x00\x00\x00\x1f\x15\xc4\x89\x00\x00\x00\nIDATx\x9cc\x00\x01\x00\x00\x05\x00\x01\r\n-\xdb\x00\x00\x00\x00IEND\xaeB`\x82'
            self.wfile.write(transparent_pixel)
    
    def handle_url_check_request(self, query_string):
        try:
            # Parse query parameters
            params = parse_qs(query_string)
            check_url = params.get('url', [''])[0]
            
            if not check_url:
                self.send_response(400)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                error_response = json.dumps({'error': 'Missing URL parameter'})
                self.wfile.write(error_response.encode())
                return
            
            print(f"Checking URL status: {check_url}")
            
            # Create request to check URL
            request = urllib.request.Request(check_url)
            request.add_header('User-Agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36')
            request.add_header('Accept', 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8')
            
            # Create SSL context that doesn't verify certificates
            ssl_context = ssl.create_default_context()
            ssl_context.check_hostname = False
            ssl_context.verify_mode = ssl.CERT_NONE
            
            # Make HEAD request to check status (faster than GET)
            request.get_method = lambda: 'HEAD'
            
            try:
                with urllib.request.urlopen(request, timeout=5, context=ssl_context) as response:
                    status_code = response.status
                    print(f"URL {check_url} returned status: {status_code}")
                    
                    # Send success response
                    self.send_response(200)
                    self.send_header('Content-Type', 'application/json')
                    self.end_headers()
                    response_data = json.dumps({
                        'url': check_url,
                        'status': status_code,
                        'success': 200 <= status_code < 400
                    })
                    self.wfile.write(response_data.encode())
                    
            except urllib.error.HTTPError as e:
                print(f"URL {check_url} returned HTTP error: {e.code}")
                # Send response with error status
                self.send_response(200)
                self.send_header('Content-Type', 'application/json')
                self.end_headers()
                response_data = json.dumps({
                    'url': check_url,
                    'status': e.code,
                    'success': False
                })
                self.wfile.write(response_data.encode())
                
        except Exception as e:
            print(f"URL check error: {type(e).__name__}: {str(e)}")
            # Send error response
            self.send_response(200)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
            response_data = json.dumps({
                'url': check_url,
                'status': 0,
                'success': False,
                'error': str(e)
            })
            self.wfile.write(response_data.encode())

def run_server(port=8000):
    with socketserver.TCPServer(("0.0.0.0", port), CORSRequestHandler) as httpd:
        print(f"Server running at http://localhost:{port}/")
        print(f"Open http://localhost:{port}/search-demo.html in your browser")
        print("Press Ctrl+C to stop the server")
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\nServer stopped.")

if __name__ == "__main__":
    port = 8000
    if len(sys.argv) > 1:
        try:
            port = int(sys.argv[1])
        except ValueError:
            print("Invalid port number. Using default port 8000.")
    
    run_server(port)
