import json
import os
import re

# List of existing collections to merge
COLLECTIONS = [
    'Catalog_Domain.postman_collection.json',
    'ConsolidatedQuotes.postman_collection.json',
    'Order_Receipt_Delivery_Log_Endpoints.postman_collection.json',
    'SupplyChain_BranchChanges.postman_collection.json',
    'repricing_v2_postman_collection.json',
    'supply_alternatives_postman_collection.json'
]

# Additional routes to parse manually from routes/apis/ (Simplified)
ROUTE_FILES = [
    'routes/apis/accounting.php',
    'routes/apis/management.php',
    'routes/apis/construction.php',
    'routes/apis/crm.php'
]

def parse_php_routes(filepath):
    """Simple regex parser for Laravel routes."""
    routes = []
    try:
        with open(filepath, 'r') as f:
            content = f.read()
            # Look for Route::get('path', ...) or post, put, etc.
            pattern = r"Route::(get|post|put|patch|delete)\(['\"](.*?)['\"]\s*,\s*\[?(.*?)\]?\)"
            matches = re.finditer(pattern, content)
            for m in matches:
                method = m.group(1).upper()
                path = m.group(2)
                action = m.group(3)
                routes.append({
                    'method': method,
                    'path': path,
                    'action': action.strip()
                })
    except Exception as e:
        print(f"Error parsing {filepath}: {e}")
    return routes

def generate_mock_response(name, method):
    """Create a realistic mock response structure."""
    if 'index' in name.lower() or 'list' in name.lower() or 'search' in name.lower():
        return {
            "data": [
                {
                    "id": 1,
                    "name": "Sample Item 1",
                    "title": "Title 1",
                    "code": "CODE001",
                    "status": "active",
                    "created_at": "2024-03-20T10:00:00Z"
                },
                {
                    "id": 2,
                    "name": "Sample Item 2",
                    "title": "Title 2",
                    "code": "CODE002",
                    "status": "pending",
                    "created_at": "2024-03-20T11:00:00Z"
                }
            ],
            "meta": {
                "current_page": 1,
                "total": 2
            }
        }
    elif 'show' in name.lower() or 'get' in name.lower():
        return {
            "data": {
                "id": 1,
                "name": "Single Resource",
                "description": "This is a detailed description of the resource.",
                "status": "active",
                "company_id": 123,
                "created_at": "2024-03-20T10:00:00Z"
            }
        }
    elif method == 'POST' or method == 'PUT' or method == 'PATCH':
        return {
            "message": "Operation completed successfully",
            "data": {
                "id": 999,
                "status": "success"
            }
        }
    else:
        return {"status": "success"}

def create_request_item(name, method, full_path, group_name="Generic"):
    """Create a Postman request item with tests and mock response."""
    # Clean up name
    clean_name = name.replace("'", "").replace('"', "").replace("[", "").replace("]", "").split("::")[-1]
    
    # Generate common tests
    tests = """
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
});

pm.test("Response is JSON", function () {
    pm.response.to.be.withBody;
    pm.response.to.be.json;
});

if (pm.response.code === 200) {
    var jsonData = pm.response.json();
    pm.test("Should have data property", function () {
        pm.expect(jsonData).to.have.property('data');
    });
}
    """

    # Generate Mock Response (Apidog format)
    mock_resp = generate_mock_response(clean_name, method)

    return {
        "name": clean_name or full_path,
        "event": [
            {
                "listen": "test",
                "script": {
                    "type": "text/javascript",
                    "exec": tests.strip().split('\n')
                }
            }
        ],
        "request": {
            "method": method,
            "header": [
                {
                    "key": "Accept",
                    "value": "application/json"
                },
                {
                    "key": "Content-Type",
                    "value": "application/json"
                }
            ],
            "url": {
                "raw": "{{baseUrl}}/api/v1/" + full_path.lstrip('/'),
                "host": ["{{baseUrl}}"],
                "path": ["api", "v1"] + [p for p in full_path.lstrip('/').split('/') if p]
            },
            "body": {
                "mode": "raw",
                "raw": "{ \"id\": 0 }",
                "options": {
                    "raw": {
                        "language": "json"
                    }
                }
            } if method in ['POST', 'PUT', 'PATCH'] else None
        },
        "response": [
            {
                "name": "Success Example",
                "status": "OK",
                "code": 200,
                "_postman_previewlanguage": "json",
                "header": [{"key": "Content-Type", "value": "application/json"}],
                "body": json.dumps(mock_resp, indent=2)
            }
        ]
    }

def augment_items(items):
    """Recursively clean and augment items."""
    # Apidog specific internal format: swap for the list
    if isinstance(items, dict) and 'value' in items:
        return augment_items(items['value'])
    
    if not isinstance(items, list):
        return items

    cleaned_items = []
    for item in items:
        # Handle the case where some items are "special" (like counts or metadata)
        if not isinstance(item, dict):
            continue

        # Handle wrongly nested Apidog items where the 'item' property itself is special
        if 'item' in item:
            item['item'] = augment_items(item['item'])

        # Augment existing requests with tests and responses
        if 'request' in item:
            if 'event' not in item:
                item['event'] = []
            
            # Use better name for responses
            method = item['request'].get('method', 'GET')
            if 'response' not in item or not item['response']:
                item['response'] = [
                    {
                        "name": "Default Mock Response",
                        "status": "OK",
                        "code": 200,
                        "_postman_previewlanguage": "json",
                        "header": [{"key": "Content-Type", "value": "application/json"}],
                        "body": json.dumps(generate_mock_response(item.get('name', 'Resource'), method), indent=2)
                    }
                ]
        cleaned_items.append(item)
    return cleaned_items

def main():
    final_items = []
    
    # 1. Load existing collections if available
    for coll_file in COLLECTIONS:
        if os.path.exists(coll_file):
            print(f"Loading collection: {coll_file}")
            try:
                with open(coll_file, 'r') as f:
                    data = json.load(f)
                    
                    # Ensure it has items
                    if 'item' in data:
                        processed_items = augment_items(data['item'])
                        final_items.append({
                            "name": data.get('info', {}).get('name', coll_file.replace('.json', '')),
                            "item": processed_items
                        })
            except Exception as e:
                print(f"Error processing {coll_file}: {e}")

    # 2. Parse PHP routes for missing modules
    for route_file in ROUTE_FILES:
        if os.path.exists(route_file):
            print(f"Parsing route file: {route_file}")
            routes = parse_php_routes(route_file)
            if routes:
                module_name = route_file.split('/')[-1].replace('.php', '').capitalize()
                folder_items = []
                for r in routes:
                    folder_items.append(create_request_item(r['action'], r['method'], r['path']))
                
                final_items.append({
                    "name": module_name + " Module",
                    "item": folder_items
                })

    # Final Postman/Apidog structure
    result = {
        "info": {
            "name": "Consolidated App API Collection",
            "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json"
        },
        "item": final_items,
        "variable": [
            {
                "key": "baseUrl",
                "value": "http://localhost",
                "type": "string"
            },
            {
                "key": "token",
                "value": "YOUR_SANCTUM_TOKEN_HERE",
                "type": "string"
            }
        ],
        "auth": {
            "type": "bearer",
            "bearer": [
                {
                    "key": "token",
                    "value": "{{token}}",
                    "type": "string"
                }
            ]
        }
    }

    with open('apidog_collection.json', 'w') as f:
        json.dump(result, f, indent=2)
    print("Generated apidog_collection.json successfully!")

if __name__ == "__main__":
    main()
