#!/usr/bin/env python3
import http.server
import socketserver
import socket
import json
import os
import urllib.parse
from pathlib import Path

class ProjectsHandler(http.server.SimpleHTTPRequestHandler):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, directory=os.getcwd(), **kwargs)
    
    def do_GET(self):
        """Handle GET requests"""
        if self.path == '/api/projects':
            self.serve_projects()
        elif self.path == '/api/products':
            self.serve_products()
        else:
            # Serve static files
            super().do_GET()
    
    def do_POST(self):
        """Handle POST requests"""
        if self.path == '/api/projects':
            self.save_projects()
        elif self.path == '/api/products':
            self.save_products()
        else:
            self.send_error(404, "Not found")
    
    def serve_projects(self):
        """Serve projects.json content"""
        try:
            with open('projects.json', 'r', encoding='utf-8') as f:
                projects_data = f.read()
            
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(projects_data.encode('utf-8'))
        except FileNotFoundError:
            # If projects.json doesn't exist, return empty object
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(b'{}')
        except Exception as e:
            print(f"Error serving projects: {e}")
            self.send_error(500, f"Internal server error: {str(e)}")
    
    def save_projects(self):
        """Save projects data to projects.json"""
        try:
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            
            # Parse JSON data
            projects_data = json.loads(post_data.decode('utf-8'))
            
            # Save to projects.json with proper formatting
            with open('projects.json', 'w', encoding='utf-8') as f:
                json.dump(projects_data, f, ensure_ascii=False, indent=2)
            
            print(f"Projects saved successfully - {len(projects_data)} projects")
            
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps({"status": "success", "message": "Projects saved successfully"}).encode('utf-8'))
            
        except json.JSONDecodeError as e:
            print(f"JSON decode error: {e}")
            self.send_error(400, f"Invalid JSON data: {str(e)}")
        except Exception as e:
            print(f"Error saving projects: {e}")
            self.send_error(500, f"Internal server error: {str(e)}")
    
    def serve_products(self):
        """Serve products.json content"""
        try:
            with open('products.json', 'r', encoding='utf-8') as f:
                products_data = f.read()
            
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(products_data.encode('utf-8'))
        except FileNotFoundError:
            # If products.json doesn't exist, return empty array
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(b'[]')
        except Exception as e:
            print(f"Error serving products: {e}")
            self.send_error(500, f"Internal server error: {str(e)}")
    
    def save_products(self):
        """Save products data to products.json"""
        try:
            content_length = int(self.headers['Content-Length'])
            post_data = self.rfile.read(content_length)
            
            # Parse JSON data
            products_data = json.loads(post_data.decode('utf-8'))
            
            # Validate that it's an array
            if not isinstance(products_data, list):
                raise ValueError("Products data must be an array")
            
            # Save to products.json with proper formatting
            with open('products.json', 'w', encoding='utf-8') as f:
                json.dump(products_data, f, ensure_ascii=False, indent=2)
            
            print(f"Products saved successfully - {len(products_data)} products")
            
            self.send_response(200)
            self.send_header('Content-Type', 'application/json; charset=utf-8')
            self.send_header('Access-Control-Allow-Origin', '*')
            self.end_headers()
            self.wfile.write(json.dumps({
                "status": "success", 
                "message": "Products saved successfully",
                "count": len(products_data)
            }).encode('utf-8'))
            
        except json.JSONDecodeError as e:
            print(f"JSON decode error: {e}")
            self.send_error(400, f"Invalid JSON data: {str(e)}")
        except ValueError as e:
            print(f"Validation error: {e}")
            self.send_error(400, f"Validation error: {str(e)}")
        except Exception as e:
            print(f"Error saving products: {e}")
            self.send_error(500, f"Internal server error: {str(e)}")
    
    def do_OPTIONS(self):
        """Handle OPTIONS requests for CORS"""
        self.send_response(200)
        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')
        self.end_headers()

def run_server(port=8003):
    """Run the custom server"""
    try:
        with socketserver.TCPServer(("", port), ProjectsHandler) as httpd:
            # Allow socket reuse to prevent "Address already in use" errors
            httpd.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            print(f"🚀 Server running at http://localhost:{port}")
            print(f"📁 Serving files from: {os.getcwd()}")
            print(f"💾 Projects will be saved to: {os.path.join(os.getcwd(), 'projects.json')}")
            print(f"📦 Products will be saved to: {os.path.join(os.getcwd(), 'products.json')}")
            print("Press Ctrl+C to stop the server")
            httpd.serve_forever()
    except KeyboardInterrupt:
        print("\n👋 Server stopped by user")
    except OSError as e:
        if e.errno == 48:  # Address already in use
            print(f"❌ Port {port} is already in use. Try a different port:")
            print(f"   python3 server.py --port {port + 1}")
        else:
            print(f"❌ Error starting server: {e}")

if __name__ == "__main__":
    import argparse
    
    parser = argparse.ArgumentParser(description='Products Calculator Server')
    parser.add_argument('--port', type=int, default=8003, help='Port to run the server on (default: 8003)')
    args = parser.parse_args()
    
    run_server(args.port) 