"""
Convolutional Neural Networks (CNNs) — comprehensive topic content with interactive graphs.
"""

import json
import numpy as np


def _convolution_demo():
    """Show a convolution operation on a small image."""
    # Original 5x5 "image"
    image = [[0, 0, 1, 1, 0],
             [0, 1, 1, 0, 0],
             [1, 1, 1, 1, 1],
             [0, 1, 1, 0, 0],
             [0, 0, 1, 0, 0]]

    # 3x3 edge detection kernel
    kernel = [[-1, -1, -1],
              [-1,  8, -1],
              [-1, -1, -1]]

    # Compute convolution result (3x3 output)
    output = []
    for i in range(3):
        row = []
        for j in range(3):
            val = sum(image[i+di][j+dj] * kernel[di][dj]
                     for di in range(3) for dj in range(3))
            row.append(val)
        output.append(row)

    data = [
        {"z": image[::-1], "type": "heatmap", "colorscale": [[0, "#1a1a3e"], [1, "#6C63FF"]],
         "showscale": False, "xaxis": "x", "yaxis": "y",
         "text": [["" for _ in r] for r in image[::-1]], "texttemplate": "%{z}", "textfont": {"size": 14, "color": "#fff"}},
    ]
    layout = {
        "template": "plotly_dark", "paper_bgcolor": "rgba(0,0,0,0)", "plot_bgcolor": "rgba(0,0,0,0)",
        "title": {"text": "Input Image (5×5) with Edge Detection Filter", "font": {"size": 18}},
        "xaxis": {"showticklabels": False}, "yaxis": {"showticklabels": False, "scaleanchor": "x"},
        "margin": {"l": 40, "r": 40, "t": 50, "b": 40},
    }
    return json.dumps({"data": data, "layout": layout})


def _feature_maps():
    """Simulate feature map hierarchy."""
    layers = ["Input\nImage", "Conv1\nEdges", "Conv2\nTextures", "Conv3\nParts", "Conv4\nObjects", "FC\nClasses"]
    channels = [3, 32, 64, 128, 256, 10]
    spatial = [224, 112, 56, 28, 14, 1]

    data = [
        {"x": layers, "y": channels, "name": "Channels (Depth)", "type": "bar",
         "marker": {"color": "#6C63FF", "line": {"width": 1.5, "color": "#fff"}},
         "text": [str(c) for c in channels], "textposition": "outside",
         "textfont": {"color": "#e0e0e0", "size": 13}},
        {"x": layers, "y": spatial, "name": "Spatial Size", "type": "scatter", "mode": "lines+markers",
         "line": {"color": "#FF6584", "width": 3}, "marker": {"size": 8}, "yaxis": "y2"},
    ]
    layout = {
        "template": "plotly_dark", "paper_bgcolor": "rgba(0,0,0,0)", "plot_bgcolor": "rgba(0,0,0,0)",
        "title": {"text": "CNN Layer Hierarchy", "font": {"size": 18}},
        "yaxis": {"title": "Number of Channels", "gridcolor": "rgba(255,255,255,0.08)"},
        "yaxis2": {"title": "Spatial Resolution", "overlaying": "y", "side": "right", "gridcolor": "rgba(255,255,255,0.04)"},
        "legend": {"x": 0.35, "y": 0.95},
        "margin": {"l": 60, "r": 60, "t": 50, "b": 80},
    }
    return json.dumps({"data": data, "layout": layout})


def _architecture_comparison():
    """Compare popular CNN architectures."""
    models = ["LeNet-5", "AlexNet", "VGG-16", "ResNet-50", "EfficientNet-B0"]
    params_m = [0.06, 61, 138, 25.6, 5.3]
    top1_acc = [99.0, 63.3, 74.4, 80.4, 77.1]
    year = [1998, 2012, 2014, 2015, 2019]

    data = [
        {"x": models, "y": top1_acc, "type": "bar",
         "marker": {"color": ["#6C63FF", "#FF6584", "#a78bfa", "#34d399", "#fbbf24"],
                    "line": {"width": 1.5, "color": "#fff"}},
         "text": [f"{a:.1f}%" for a in top1_acc], "textposition": "outside",
         "textfont": {"color": "#e0e0e0", "size": 13}},
    ]
    layout = {
        "template": "plotly_dark", "paper_bgcolor": "rgba(0,0,0,0)", "plot_bgcolor": "rgba(0,0,0,0)",
        "title": {"text": "ImageNet Top-1 Accuracy by CNN Architecture", "font": {"size": 18}},
        "yaxis": {"title": "Top-1 Accuracy (%)", "gridcolor": "rgba(255,255,255,0.08)", "range": [55, 85]},
        "margin": {"l": 60, "r": 30, "t": 50, "b": 50},
    }
    return json.dumps({"data": data, "layout": layout})


def get_content() -> dict:
    return {
        "title": "Convolutional Neural Networks",
        "icon": "🖼️",
        "subtitle": "Deep learning for images, video, and spatial data",
        "sections": [
            {"id": "introduction", "heading": "What are CNNs?", "type": "text",
             "content": ("Convolutional Neural Networks are specialized neural networks designed for <strong>grid-like data</strong> "
                         "such as images. Instead of connecting every neuron to every input, CNNs use <strong>learnable filters</strong> "
                         "(kernels) that slide across the input, detecting patterns like edges, textures, and shapes.\n\n"
                         "CNNs are the backbone of computer vision — from image classification to object detection to face recognition.")},
            {"id": "convolution", "heading": "The Convolution Operation", "type": "graph",
             "description": "A small filter slides over the input image, computing a dot product at each position. Different filters detect different features (edges, corners, textures).",
             "graph_json": _convolution_demo()},
            {"id": "layers", "heading": "CNN Building Blocks", "type": "list",
             "entries": [
                 {"title": "Convolutional Layer", "detail": "Applies learnable filters to extract features. Preserves spatial relationships. Parameters: kernel_size, stride, padding, num_filters."},
                 {"title": "Activation (ReLU)", "detail": "Applied after each conv layer. f(x) = max(0, x). Introduces non-linearity."},
                 {"title": "Pooling Layer", "detail": "Reduces spatial dimensions. Max pooling (take the max in each window) is most common. Provides translation invariance."},
                 {"title": "Batch Normalization", "detail": "Normalizes layer outputs. Stabilizes training and allows higher learning rates."},
                 {"title": "Fully Connected Layer", "detail": "After conv layers flatten the features, FC layers perform the final classification."},
                 {"title": "Dropout", "detail": "Randomly zeros neurons during training. Prevents co-adaptation and reduces overfitting."},
             ]},
            {"id": "hierarchy", "heading": "Feature Hierarchy", "type": "graph",
             "description": "Early layers detect simple features (edges). Deeper layers combine them into complex patterns (textures → parts → objects). Spatial resolution decreases while depth (channels) increases.",
             "graph_json": _feature_maps()},
            {"id": "math", "heading": "The Mathematics", "type": "math",
             "content": [
                 {"label": "2D Convolution", "formula": "(I * K)(i,j) = \\sum_{m} \\sum_{n} I(i+m, j+n) \\cdot K(m, n)",
                  "explanation": "The filter K slides over image I. At each position, compute the element-wise product and sum."},
                 {"label": "Output Size", "formula": "O = \\frac{W - K + 2P}{S} + 1",
                  "explanation": "W = input size, K = kernel size, P = padding, S = stride. Determines the spatial dimensions of the output."},
                 {"label": "Parameter Count", "formula": "\\text{Params} = K^2 \\times C_{in} \\times C_{out} + C_{out}",
                  "explanation": "K² kernel size × input channels × output channels + biases. Much fewer params than fully connected layers."},
             ]},
            {"id": "architectures", "heading": "Famous Architectures", "type": "graph",
             "description": "The evolution of CNN architectures on ImageNet. ResNet introduced skip connections enabling 100+ layer networks. EfficientNet optimizes accuracy per parameter.",
             "graph_json": _architecture_comparison()},
            {"id": "implementation", "heading": "Python Implementation", "type": "code", "language": "python",
             "content": ("import torch\nimport torch.nn as nn\n\nclass SimpleCNN(nn.Module):\n"
                         "    def __init__(self, num_classes=10):\n        super().__init__()\n"
                         "        self.features = nn.Sequential(\n"
                         "            nn.Conv2d(3, 32, kernel_size=3, padding=1),\n"
                         "            nn.BatchNorm2d(32),\n"
                         "            nn.ReLU(),\n"
                         "            nn.MaxPool2d(2),\n\n"
                         "            nn.Conv2d(32, 64, kernel_size=3, padding=1),\n"
                         "            nn.BatchNorm2d(64),\n"
                         "            nn.ReLU(),\n"
                         "            nn.MaxPool2d(2),\n\n"
                         "            nn.Conv2d(64, 128, kernel_size=3, padding=1),\n"
                         "            nn.BatchNorm2d(128),\n"
                         "            nn.ReLU(),\n"
                         "            nn.AdaptiveAvgPool2d(1),\n"
                         "        )\n"
                         "        self.classifier = nn.Sequential(\n"
                         "            nn.Flatten(),\n"
                         "            nn.Linear(128, 64),\n"
                         "            nn.ReLU(),\n"
                         "            nn.Dropout(0.5),\n"
                         "            nn.Linear(64, num_classes),\n"
                         "        )\n\n"
                         "    def forward(self, x):\n"
                         "        x = self.features(x)\n"
                         "        return self.classifier(x)\n\n"
                         "model = SimpleCNN(num_classes=10)\n"
                         "print(f'Parameters: {sum(p.numel() for p in model.parameters()):,}')\n")},
            {"id": "tips", "heading": "Key Takeaways", "type": "list",
             "entries": [
                 {"title": "Transfer Learning", "detail": "Don't train from scratch. Use pretrained models (ResNet, EfficientNet) and fine-tune on your data. Works with even 100 images."},
                 {"title": "Data Augmentation", "detail": "Flip, rotate, crop, color jitter. Artificially increases dataset size and prevents overfitting."},
                 {"title": "Start Small", "detail": "Begin with a simple architecture. Add complexity only if validation performance is insufficient."},
                 {"title": "Use Pre-built Models", "detail": "torchvision.models and timm libraries provide optimized, pre-trained architectures ready to use."},
             ]},
        ],
    }
