"""
Example app demonstrating custom configuration with Pydantic models.

This app shows how to define app-specific configuration schemas using Pydantic
and access validated config values in your app interface.
"""

from typing import Optional

import gradio as gr
from pydantic import BaseModel, Field

from apps.base_app import BaseApp


class TestConfigModel(BaseModel):
    """Configuration schema for test_config app."""

    api_endpoint: str = Field(description="API endpoint URL")
    api_key: Optional[str] = Field(
        default=None, description="API key for authentication"
    )
    max_retries: int = Field(default=3, description="Maximum number of retries")
    timeout: int = Field(default=30, description="Request timeout in seconds")
    enable_feature: bool = Field(default=True, description="Enable special feature")


class TestConfigApp(BaseApp[TestConfigModel]):
    """
    Test app demonstrating custom configuration.

    This app demonstrates how to:
    1. Define a Pydantic model for app-specific configuration
    2. Access validated config values from config.yaml
    3. Use type-safe configuration in your app logic with full IDE support
    """

    # Set the configuration model class
    ConfigModel = TestConfigModel

    def create_interface(self) -> gr.Blocks:
        """Create the test configuration interface."""
        with gr.Blocks() as interface:
            gr.Markdown(f"## {self.title}")
            gr.Markdown("This app demonstrates the app-specific configuration feature.")

            if self.config:
                # Configuration is loaded and validated
                self.log_info(f"Config loaded: {self.config.api_endpoint}")

                gr.Markdown("### ✅ Configuration Loaded Successfully")
                gr.Markdown(
                    "The following configuration was loaded from `config.yaml`:"
                )

                with gr.Group():
                    gr.Markdown(f"**API Endpoint:** `{self.config.api_endpoint}`")
                    gr.Markdown(
                        f"**API Key:** `{'***' if self.config.api_key else 'Not set'}`"
                    )
                    gr.Markdown(f"**Max Retries:** {self.config.max_retries}")
                    gr.Markdown(f"**Timeout:** {self.config.timeout} seconds")
                    gr.Markdown(f"**Feature Enabled:** {self.config.enable_feature}")

                gr.Markdown("---")
                gr.Markdown("### How This Works")
                gr.Markdown("""
                **Step 1:** Define a Pydantic model in your app file:
                ```python
                class TestConfigModel(BaseModel):
                    api_endpoint: str = Field(description="API endpoint URL")
                    max_retries: int = Field(default=3, description="Max retries")
                    # ... more fields
                ```

                **Step 2:** Override the `ConfigModel` property:
                ```python
                @property
                def ConfigModel(self):
                    return TestConfigModel
                ```

                **Step 3:** Add config to `config.yaml`:
                ```yaml
                apps:
                  test_config:
                    title: "Config Test"
                    config:
                      api_endpoint: "https://api.example.com/v1"
                      max_retries: 5
                ```

                **Step 4:** Access validated config in your app:
                ```python
                endpoint = self.config.api_endpoint
                retries = self.config.max_retries
                ```
                """)

                gr.Markdown("---")
                gr.Markdown("### Try It Out")
                gr.Markdown("Test how the configuration values are used:")

                with gr.Row():
                    test_input = gr.Textbox(
                        label="Test Input",
                        placeholder="Enter some text to test the feature...",
                        value="Hello, Config!",
                    )

                test_btn = gr.Button("Process with Config", variant="primary")
                test_output = gr.Textbox(label="Output", lines=5)

                def process_with_config(text: str) -> str:
                    """Demonstrate using config values in app logic."""
                    if not self.config:
                        return "Error: Configuration not loaded"

                    self.log_info(
                        f"Processing with endpoint: {self.config.api_endpoint}"
                    )

                    # Simulate using config values
                    output_lines = [
                        f"Input: {text}",
                        "",
                        "Simulated API Call:",
                        f"  Endpoint: {self.config.api_endpoint}",
                        f"  Max Retries: {self.config.max_retries}",
                        f"  Timeout: {self.config.timeout}s",
                        f"  Feature Enabled: {self.config.enable_feature}",
                        "",
                        "Result: Processing completed successfully!",
                    ]

                    if self.config.enable_feature:
                        output_lines.append(
                            f"Special feature applied to: {text.upper()}"
                        )

                    return "\n".join(output_lines)

                test_btn.click(
                    fn=process_with_config, inputs=test_input, outputs=test_output
                )

            else:
                # Configuration not found or failed to parse
                self.log_warning("Config not found for test_config app")

                gr.Markdown("### ⚠️ Configuration Not Found")
                gr.Markdown("""
                No configuration was found in `config.yaml` for this app.

                To enable configuration:
                1. Add a `config:` section under `test_config:` in `config.yaml`
                2. Define your configuration fields
                3. Restart the application

                See `.copilot/context/configuration.md` for detailed instructions on app-specific configuration.
                """)

            gr.Markdown("---")
            gr.Markdown("### 📖 Documentation")
            gr.Markdown("""
            For more information about app-specific configuration:
            - See `.copilot/context/configuration.md` - App-specific configuration guide
            - See `.copilot/context/app-architecture.md` - Complete app development guide
            - Check `config.yaml` - Look for the `test_config` app configuration
            - View `apps/test_config.py` - This file's source code
            """)

        return interface


# Export the app class
app = TestConfigApp
