from factors.expression_lib import init_expression_lib, get_implementation_source
from factors.register import DynamicFactorRuntime

EFS_SYSTEM_PROMPT = """
You are a world-class quantitative researcher and Python programmer specializing in alpha factor design for asset ranking. 
Your task is to generate high-quality Python factor functions that are evolved versions of provided factors.

STRICT REQUIREMENTS:
1. Output ONLY a Python list of function strings - no comments or explanations
2. Each function MUST:
   - Be bug-free and executable
   - Maintain identical input signature: prices, window≤
   - Use only numpy (as np), don't depend on any external function or variable, you need to do computation all inside function
   - Handle edge cases (short series, NaNs)
   - Clearly indicate if combining or modifying existing factors
3. Absolute prohibitions:
   - No external functions
   - No hardcoded values that should be parameters
   - No pandas or other libraries
   - No comments in output code
4. Factor name rules: [factor_name_part]_[window_size]_v[version number], the window_size can only be the following value: 3, 7, 14, 21
5. Value of output factor: For factors, higher value means better asset, please make sure the output value is positve related to performance of assets.

ACTION SPACE:
1. Improve existing factors by mutation:
    - Modifying parameters (e.g., inner paremeters)
    - Adjusting logic
    - Updating inside operators for factors
2. Improve existing factors by crossover:
    - Combining two existing factors to create a new one if you think they can work together
    - Restart version number from v1 for new factors

IMPROVEMENT CRITERIA:
1. Version increments must show clear:
- if you improve from a given version, increa 1 to veroin number, the version number can only be integer like v1, v2, v3, don't include any other character.
   - Performance enhancement
   - Robustness improvement
   - Computational efficiency
- if you create a new factor by cross over from other two, restart from version number from v1, and use the name like: factor1_comb_factor2, where factor1 and factor2 are the names of the two factors you combined.
2. Combined factors should demonstrate:
   - Logical interaction
   - Complementary strengths
   - Better risk-adjusted returns
   - Don't make combined factors too complex, try to keep it simple and easy to understand.
    
For string version of function, you should be very careful about format of python, for example:
"def test_run_avg(*args, **kwargs):\n    a=np.array(prices)\n    if a:\n        print(a)\n    return np.mean(kwargs['prices'])\n"
Becare ful of symbol split the line, the different space of tab for if statement.

To help you think the result, please also use enable chain of thought reasoning, and output the result in a list of string (all think in one output), like:
Output example:
{
    "codes": ["def momentum_7_v3(prices, window=10): return ...", "def breakout_comb_meanrevert_21_v1(prices, window=20): return ..."],
    "thinking": "I have improved the momentum factor by adjusting the window size and logic to enhance its performance. The new factor combines breakout and mean reversion strategies to capture both trends and reversals effectively."
}
"""

def create_str_expression_source(name):
    if "strat_" in name:
        code_impl = get_implementation_source(
            name.split("strat_")[1], init_expression_lib
        )
    else:
        code_impl = get_implementation_source(name, init_expression_lib)
    return code_impl


def generate_recent_performance_report(
    benchmark_result, factor_quality, portfolop_performance
):
    report = f"""The benchmark result (equally weighted): Latest value:
    final_value={benchmark_result['portfolio_values'][-1]}
    mean_return={benchmark_result['mean_return']}  std_return={benchmark_result['std_return']}
    max_drawdown={benchmark_result['max_drawdown']} sharpe_ratio={benchmark_result['sharpe_ratio']}\n"""
    report += (
        f"Here is portfolio performance of each factor:\n {portfolop_performance}\n"
    )
    report += f"Here is factor quality (RankIC of asets score and daily return (higher means better), and recall (shot rate of good assets):\n {factor_quality}\n)"
    return report


def generate_factor_generate_prompt(
    factor_list, recent_performance, recent_quality, n=5, max_window=30
):
    factors_str = "\n".join(
        f"# Previous best version:\n{factor}\n" for factor in factor_list
    )

    return f"""
You are an expert factor optimizer. Critically evolutionary improve existing factors based on performance to generate {n} new factors.

Here is infformation about the factors you need to improve:
Existing Factors:
{factors_str}

Performance Analysis:
{recent_performance}

Factor Quality:
{recent_quality}

 """
