import { z } from "zod";
import type { InsightRow } from "../types/meta-api.js";

const baseStyles = `
  * { margin: 0; padding: 0; box-sizing: border-box; }
  body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #1a1a2e; color: #eee; padding: 20px; }
  .container { max-width: 1400px; margin: 0 auto; }
  h1 { font-size: 28px; margin-bottom: 24px; color: #fff; }
  .heatmap-container { background: #16213e; border-radius: 12px; padding: 32px; margin-bottom: 24px; box-shadow: 0 4px 12px rgba(0,0,0,0.3); overflow-x: auto; }
  .heatmap-grid { display: grid; grid-template-columns: 80px repeat(24, 1fr); gap: 4px; min-width: 1200px; }
  .heatmap-cell { aspect-ratio: 1; display: flex; align-items: center; justify-content: center; border-radius: 4px; font-size: 10px; font-weight: 600; }
  .day-label { display: flex; align-items: center; justify-content: flex-start; padding-left: 8px; font-size: 13px; font-weight: 600; color: #fff; }
  .hour-label { display: flex; align-items: center; justify-content: center; font-size: 11px; color: #999; }
  .legend { display: flex; align-items: center; gap: 16px; margin-top: 24px; padding-top: 24px; border-top: 1px solid #0f3460; }
  .legend-label { color: #999; font-size: 13px; font-weight: 600; }
  .legend-gradient { height: 24px; width: 300px; border-radius: 4px; background: linear-gradient(90deg, #0f3460, #3498db, #e94560, #ff6b9d); }
  .legend-values { display: flex; justify-content: space-between; width: 300px; margin-top: 4px; font-size: 11px; color: #777; }
  .insights { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
  .insight-card { background: #0f3460; border-radius: 8px; padding: 16px; }
  .insight-card h3 { font-size: 12px; color: #999; text-transform: uppercase; margin-bottom: 8px; }
  .insight-card .value { font-size: 20px; font-weight: 700; color: #e94560; }
  .insight-card .sublabel { font-size: 11px; color: #777; margin-top: 4px; }
  .error { background: #16213e; padding: 40px; border-radius: 12px; text-align: center; color: #e94560; }
`;

export function register(server: any, client: any): void {
  server.tool(
    "performance_heatmap",
    "Performance Heatmap - Hourly performance visualization across days and hours",
    {
      account_id: z.string().optional().describe("Ad Account ID (format: act_XXXXX)"),
      campaign_id: z.string().optional().describe("Campaign ID (either account_id or campaign_id required)"),
      date_preset: z.enum([
        "last_7d", "last_14d"
      ]).optional().default("last_7d").describe("Date range preset"),
      metric: z.enum(["ctr", "cpc", "cpm", "conversions", "roas"]).optional().default("ctr").describe("Metric to visualize")
    },
    async (params: { account_id?: string; campaign_id?: string; date_preset?: string; metric?: string }) => {
      try {
        if (!params.account_id && !params.campaign_id) {
          throw new Error("Either account_id or campaign_id must be provided");
        }

        const targetId = params.campaign_id || params.account_id;
        const metric = params.metric || "ctr";

        // Fetch hourly breakdown insights
        const insightsResponse = await client.get(
          `/${targetId}/insights`,
          {
            level: params.campaign_id ? "campaign" : "account",
            date_preset: params.date_preset || "last_7d",
            time_increment: "1",
            breakdowns: "hourly_stats_aggregated_by_advertiser_time_zone",
            fields: "impressions,clicks,spend,ctr,cpc,cpm,actions,action_values"
          }
        ) as { data: InsightRow[] };
        
        const insights = insightsResponse.data;

        // Parse hourly data into 7x24 grid
        const days = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
        const heatmapData: number[][] = Array(7).fill(0).map(() => Array(24).fill(0));
        const counts: number[][] = Array(7).fill(0).map(() => Array(24).fill(0));

        insights.forEach((insight: InsightRow) => {
          // Parse date and hour from insight
          const dateStr = insight.date_start;
          const hourlyStats = (insight as any).hourly_stats_aggregated_by_advertiser_time_zone;
          
          if (!hourlyStats) return;

          const date = new Date(dateStr);
          const dayOfWeek = date.getDay();

          hourlyStats.forEach((hourStat: any) => {
            const hour = parseInt(hourStat.hour || "0");
            
            let value = 0;
            if (metric === "ctr") {
              value = parseFloat(hourStat.ctr || "0");
            } else if (metric === "cpc") {
              value = parseFloat(hourStat.cpc || "0");
            } else if (metric === "cpm") {
              value = parseFloat(hourStat.cpm || "0");
            } else if (metric === "conversions") {
              const conversions = hourStat.actions?.find((a: any) => 
                a.action_type === "purchase" || a.action_type === "offsite_conversion.fb_pixel_purchase"
              )?.value || "0";
              value = parseInt(conversions);
            } else if (metric === "roas") {
              const spend = parseFloat(hourStat.spend || "0");
              const revenue = hourStat.action_values?.find((a: any) => 
                a.action_type === "purchase" || a.action_type === "offsite_conversion.fb_pixel_purchase"
              )?.value || "0";
              value = spend > 0 ? parseFloat(revenue) / spend : 0;
            }

            heatmapData[dayOfWeek][hour] += value;
            counts[dayOfWeek][hour] += 1;
          });
        });

        // Average the values
        for (let day = 0; day < 7; day++) {
          for (let hour = 0; hour < 24; hour++) {
            if (counts[day][hour] > 0) {
              heatmapData[day][hour] /= counts[day][hour];
            }
          }
        }

        // Find min/max for color scaling
        let minValue = Infinity;
        let maxValue = -Infinity;
        let bestSlot = { day: 0, hour: 0, value: -Infinity };
        let worstSlot = { day: 0, hour: 0, value: Infinity };

        for (let day = 0; day < 7; day++) {
          for (let hour = 0; hour < 24; hour++) {
            const value = heatmapData[day][hour];
            if (counts[day][hour] > 0) {
              minValue = Math.min(minValue, value);
              maxValue = Math.max(maxValue, value);
              
              if (value > bestSlot.value) {
                bestSlot = { day, hour, value };
              }
              if (value < worstSlot.value) {
                worstSlot = { day, hour, value };
              }
            }
          }
        }

        // Calculate average
        let totalValue = 0;
        let totalCount = 0;
        for (let day = 0; day < 7; day++) {
          for (let hour = 0; hour < 24; hour++) {
            if (counts[day][hour] > 0) {
              totalValue += heatmapData[day][hour];
              totalCount++;
            }
          }
        }
        const avgValue = totalCount > 0 ? totalValue / totalCount : 0;

        // Generate color for cell based on value
        const getColor = (value: number, count: number) => {
          if (count === 0) return "#0f3460";
          const normalized = maxValue > minValue ? (value - minValue) / (maxValue - minValue) : 0.5;
          
          if (normalized < 0.25) return "#0f3460";
          if (normalized < 0.5) return "#3498db";
          if (normalized < 0.75) return "#e94560";
          return "#ff6b9d";
        };

        // Build HTML
        const html = `<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Performance Heatmap</title>
  <style>${baseStyles}</style>
</head>
<body>
  <div class="container">
    <h1>🔥 Performance Heatmap - ${metric.toUpperCase()}</h1>
    
    <div class="heatmap-container">
      <div class="heatmap-grid">
        <div></div>
        ${Array.from({ length: 24 }, (_, i) => `
          <div class="hour-label">${i === 0 ? '12a' : i < 12 ? i + 'a' : i === 12 ? '12p' : (i - 12) + 'p'}</div>
        `).join('')}
        
        ${days.map((day, dayIndex) => `
          <div class="day-label">${day}</div>
          ${Array.from({ length: 24 }, (_, hour) => {
            const value = heatmapData[dayIndex][hour];
            const count = counts[dayIndex][hour];
            const color = getColor(value, count);
            const displayValue = value > 0 ? (metric === "ctr" || metric === "roas" ? value.toFixed(1) : value.toFixed(0)) : "-";
            
            return `
              <div class="heatmap-cell" style="background: ${color}; color: ${count > 0 ? '#fff' : '#555'};" title="${day} ${hour}:00 - ${displayValue}">
                ${count > 0 ? displayValue : ''}
              </div>
            `;
          }).join('')}
        `).join('')}
      </div>
      
      <div class="legend">
        <div class="legend-label">Intensity:</div>
        <div>
          <div class="legend-gradient"></div>
          <div class="legend-values">
            <span>Low</span>
            <span>Medium</span>
            <span>High</span>
          </div>
        </div>
      </div>
    </div>
    
    <div class="insights">
      <div class="insight-card">
        <h3>Average ${metric.toUpperCase()}</h3>
        <div class="value">${avgValue > 0 ? (metric === "ctr" || metric === "roas" ? avgValue.toFixed(2) : avgValue.toFixed(0)) : '-'}</div>
        <div class="sublabel">across all time slots</div>
      </div>
      <div class="insight-card">
        <h3>Best Time Slot</h3>
        <div class="value">${days[bestSlot.day]} ${bestSlot.hour}:00</div>
        <div class="sublabel">${bestSlot.value > 0 ? (metric === "ctr" || metric === "roas" ? bestSlot.value.toFixed(2) : bestSlot.value.toFixed(0)) : '-'} ${metric}</div>
      </div>
      <div class="insight-card">
        <h3>Worst Time Slot</h3>
        <div class="value">${days[worstSlot.day]} ${worstSlot.hour}:00</div>
        <div class="sublabel">${worstSlot.value > 0 ? (metric === "ctr" || metric === "roas" ? worstSlot.value.toFixed(2) : worstSlot.value.toFixed(0)) : '-'} ${metric}</div>
      </div>
    </div>
  </div>
</body>
</html>`;

        const textSummary = `Performance Heatmap - ${metric.toUpperCase()} (${params.date_preset || "last_7d"})\n\n` +
          `Average: ${avgValue > 0 ? avgValue.toFixed(2) : 'N/A'}\n` +
          `Best: ${days[bestSlot.day]} ${bestSlot.hour}:00 (${bestSlot.value.toFixed(2)})\n` +
          `Worst: ${days[worstSlot.day]} ${worstSlot.hour}:00 (${worstSlot.value.toFixed(2)})`;

        return {
          structuredContent: {
            type: "resource",
            resource: {
              uri: "meta-ads://app/performance-heatmap",
              mimeType: "text/html",
              text: html
            }
          },
          content: [{ type: "text", text: textSummary }]
        };
      } catch (error: any) {
        const errorHtml = `<!DOCTYPE html>
<html>
<head><meta charset="utf-8"><title>Error</title><style>${baseStyles}</style></head>
<body><div class="container"><div class="error"><h2>⚠️ Error Loading Heatmap</h2><p>${error.message}</p></div></div></body>
</html>`;
        
        return {
          structuredContent: {
            type: "resource",
            resource: { uri: "meta-ads://app/performance-heatmap", mimeType: "text/html", text: errorHtml }
          },
          content: [{ type: "text", text: `Error: ${error.message}` }]
        };
      }
    },
    { title: "🔥 Performance Heatmap", readOnlyHint: true }
  );
}
