{
  "name": "Weekly SEO Report Generator",
  "nodes": [
    {
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      },
      "id": "weekly-trigger",
      "name": "Every Monday 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1.1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{$env.APP_URL}}/api/n8n/report/weekly",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 60000
        }
      },
      "id": "fetch-weekly-stats",
      "name": "Fetch Weekly Stats",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        470,
        300
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{$env.APP_URL}}/api/gsc/performance?days=7",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {}
      },
      "id": "fetch-gsc-weekly",
      "name": "Fetch GSC Weekly",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.1,
      "position": [
        470,
        500
      ],
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "mode": "combine",
        "mergeByFields": {
          "values": []
        },
        "options": {}
      },
      "id": "merge-data",
      "name": "Merge All Data",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 2.1,
      "position": [
        690,
        400
      ]
    },
    {
      "parameters": {
        "jsCode": "// Generate HTML Report\nconst data = $input.all();\nconst stats = data[0]?.json || {};\nconst gsc = data[1]?.json || {};\n\nconst weekStart = new Date();\nweekStart.setDate(weekStart.getDate() - 7);\nconst weekEnd = new Date();\n\nconst formatDate = (d) => d.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });\nconst formatNumber = (n) => n?.toLocaleString() || '0';\nconst formatPercent = (n) => ((n || 0) * 100).toFixed(1) + '%';\n\n// Calculate trends\nconst clicksTrend = stats.clicksChange > 0 ? '\u2191' : stats.clicksChange < 0 ? '\u2193' : '\u2192';\nconst impressionsTrend = stats.impressionsChange > 0 ? '\u2191' : stats.impressionsChange < 0 ? '\u2193' : '\u2192';\n\nconst html = `\n<!DOCTYPE html>\n<html>\n<head>\n  <meta charset=\"UTF-8\">\n  <style>\n    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; line-height: 1.6; color: #333; max-width: 800px; margin: 0 auto; padding: 20px; }\n    .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 12px; margin-bottom: 30px; }\n    .header h1 { margin: 0 0 10px 0; font-size: 28px; }\n    .header p { margin: 0; opacity: 0.9; }\n    .metrics-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 20px; margin-bottom: 30px; }\n    .metric-card { background: #f8f9fa; border-radius: 12px; padding: 20px; }\n    .metric-card h3 { margin: 0 0 5px 0; color: #666; font-size: 14px; text-transform: uppercase; }\n    .metric-card .value { font-size: 32px; font-weight: 700; color: #333; }\n    .metric-card .trend { font-size: 14px; margin-top: 5px; }\n    .trend.up { color: #22c55e; }\n    .trend.down { color: #ef4444; }\n    .trend.neutral { color: #666; }\n    .section { margin-bottom: 30px; }\n    .section h2 { color: #333; border-bottom: 2px solid #667eea; padding-bottom: 10px; }\n    table { width: 100%; border-collapse: collapse; }\n    th, td { padding: 12px; text-align: left; border-bottom: 1px solid #eee; }\n    th { background: #f8f9fa; font-weight: 600; }\n    tr:hover { background: #f8f9fa; }\n    .position { display: inline-block; width: 40px; height: 40px; line-height: 40px; text-align: center; border-radius: 50%; font-weight: 600; }\n    .position.top3 { background: #fef3c7; color: #d97706; }\n    .position.top10 { background: #dcfce7; color: #16a34a; }\n    .position.other { background: #f3f4f6; color: #666; }\n    .footer { text-align: center; padding: 20px; color: #666; font-size: 12px; border-top: 1px solid #eee; margin-top: 30px; }\n  </style>\n</head>\n<body>\n  <div class=\"header\">\n    <h1>\ud83d\udcca Weekly SEO Report</h1>\n    <p>${formatDate(weekStart)} - ${formatDate(weekEnd)}</p>\n  </div>\n  \n  <div class=\"metrics-grid\">\n    <div class=\"metric-card\">\n      <h3>Total Clicks</h3>\n      <div class=\"value\">${formatNumber(stats.totalClicks || gsc.clicks)}</div>\n      <div class=\"trend ${stats.clicksChange > 0 ? 'up' : stats.clicksChange < 0 ? 'down' : 'neutral'}\">\n        ${clicksTrend} ${Math.abs(stats.clicksChange || 0).toFixed(1)}% vs last week\n      </div>\n    </div>\n    <div class=\"metric-card\">\n      <h3>Total Impressions</h3>\n      <div class=\"value\">${formatNumber(stats.totalImpressions || gsc.impressions)}</div>\n      <div class=\"trend ${stats.impressionsChange > 0 ? 'up' : stats.impressionsChange < 0 ? 'down' : 'neutral'}\">\n        ${impressionsTrend} ${Math.abs(stats.impressionsChange || 0).toFixed(1)}% vs last week\n      </div>\n    </div>\n    <div class=\"metric-card\">\n      <h3>Average CTR</h3>\n      <div class=\"value\">${formatPercent(stats.avgCtr || gsc.ctr)}</div>\n    </div>\n    <div class=\"metric-card\">\n      <h3>Average Position</h3>\n      <div class=\"value\">${(stats.avgPosition || gsc.position || 0).toFixed(1)}</div>\n    </div>\n  </div>\n  \n  <div class=\"section\">\n    <h2>\ud83c\udfaf Top Performing Queries</h2>\n    <table>\n      <thead>\n        <tr>\n          <th>Query</th>\n          <th>Clicks</th>\n          <th>Impressions</th>\n          <th>CTR</th>\n          <th>Position</th>\n        </tr>\n      </thead>\n      <tbody>\n        ${(stats.topQueries || []).slice(0, 10).map(q => `\n        <tr>\n          <td>${q.query || q.keys?.[0] || 'N/A'}</td>\n          <td>${formatNumber(q.clicks)}</td>\n          <td>${formatNumber(q.impressions)}</td>\n          <td>${formatPercent(q.ctr)}</td>\n          <td><span class=\"position ${q.position <= 3 ? 'top3' : q.position <= 10 ? 'top10' : 'other'}\">${q.position?.toFixed(1)}</span></td>\n        </tr>\n        `).join('')}\n      </tbody>\n    </table>\n  </div>\n  \n  <div class=\"section\">\n    <h2>\ud83d\udcc4 Top Pages</h2>\n    <table>\n      <thead>\n        <tr>\n          <th>Page</th>\n          <th>Clicks</th>\n          <th>Impressions</th>\n          <th>CTR</th>\n        </tr>\n      </thead>\n      <tbody>\n        ${(stats.topPages || []).slice(0, 10).map(p => `\n        <tr>\n          <td style=\"max-width: 300px; overflow: hidden; text-overflow: ellipsis;\">${p.page || p.keys?.[0] || 'N/A'}</td>\n          <td>${formatNumber(p.clicks)}</td>\n          <td>${formatNumber(p.impressions)}</td>\n          <td>${formatPercent(p.ctr)}</td>\n        </tr>\n        `).join('')}\n      </tbody>\n    </table>\n  </div>\n  \n  ${stats.contentCreated?.length > 0 ? `\n  <div class=\"section\">\n    <h2>\u270d\ufe0f Content Created This Week</h2>\n    <ul>\n      ${stats.contentCreated.map(c => `<li><strong>${c.title}</strong> - ${c.type} (${formatDate(new Date(c.createdAt))})</li>`).join('')}\n    </ul>\n  </div>\n  ` : ''}\n  \n  <div class=\"section\">\n    <h2>\ud83d\udca1 Recommendations</h2>\n    <ul>\n      ${(stats.recommendations || [\n        'Optimize meta descriptions for queries with high impressions but low CTR',\n        'Create content targeting queries where you rank position 5-15',\n        'Update and expand content for top-performing pages'\n      ]).map(r => `<li>${r}</li>`).join('')}\n    </ul>\n  </div>\n  \n  <div class=\"footer\">\n    <p>Generated by Maximo SEO Report \u2022 ${new Date().toISOString()}</p>\n    <p>This report was automatically generated. Do not reply to this email.</p>\n  </div>\n</body>\n</html>\n`;\n\nreturn [{ json: { html, subject: `\ud83d\udcca Weekly SEO Report: ${formatDate(weekStart)} - ${formatDate(weekEnd)}`, stats, gsc } }];"
      },
      "id": "generate-html",
      "name": "Generate HTML Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        910,
        400
      ]
    },
    {
      "parameters": {
        "fromEmail": "={{$env.REPORT_FROM_EMAIL}}",
        "toEmail": "={{$env.STAKEHOLDER_EMAILS}}",
        "subject": "={{ $json.subject }}",
        "emailType": "html",
        "html": "={{ $json.html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "id": "send-report-email",
      "name": "Email to Stakeholders",
      "type": "n8n-nodes-base.emailSend",
      "typeVersion": 2.1,
      "position": [
        1130,
        400
      ],
      "credentials": {
        "smtp": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "={{$env.REPORTS_SHEETS_ID}}",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Weekly Reports Log",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "defineBelow",
          "value": {
            "date": "={{ new Date().toISOString() }}",
            "clicks": "={{ $json.stats?.totalClicks || 0 }}",
            "impressions": "={{ $json.stats?.totalImpressions || 0 }}",
            "ctr": "={{ $json.stats?.avgCtr || 0 }}",
            "position": "={{ $json.stats?.avgPosition || 0 }}",
            "status": "sent"
          }
        },
        "options": {}
      },
      "id": "log-report",
      "name": "Log Report Sent",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.2,
      "position": [
        1350,
        400
      ],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      }
    }
  ],
  "connections": {
    "Every Monday 8 AM": {
      "main": [
        [
          {
            "node": "Fetch Weekly Stats",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch GSC Weekly",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Weekly Stats": {
      "main": [
        [
          {
            "node": "Merge All Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch GSC Weekly": {
      "main": [
        [
          {
            "node": "Merge All Data",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge All Data": {
      "main": [
        [
          {
            "node": "Generate HTML Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate HTML Report": {
      "main": [
        [
          {
            "node": "Email to Stakeholders",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Email to Stakeholders": {
      "main": [
        [
          {
            "node": "Log Report Sent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "staticData": null,
  "tags": [
    "SEO",
    "Reporting",
    "Email",
    "Weekly"
  ],
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "versionId": "1.0.0"
}