import { logError } from "@/lib/logger";
import { NextRequest, NextResponse } from "next/server";
import { query } from "@/lib/db";

export const runtime = "nodejs";

// ─── Ensure tables exist ───────────────────────────────────────────────────────

async function ensureTablesExist() {
  try {
    await query(`
      CREATE TABLE IF NOT EXISTS internal_email_recipients (
        id          BIGSERIAL PRIMARY KEY,
        email       VARCHAR(255) NOT NULL,
        name        VARCHAR(255) NOT NULL DEFAULT '',
        is_active   BOOLEAN NOT NULL DEFAULT true,
        created_by  BIGINT NOT NULL DEFAULT 0,
        created_at  TIMESTAMPTZ NOT NULL DEFAULT NOW(),
        updated_at  TIMESTAMPTZ NOT NULL DEFAULT NOW()
      )
    `);
    await query(`
      CREATE INDEX IF NOT EXISTS idx_internal_email_recipients_email
      ON internal_email_recipients (LOWER(email))
    `);
    await query(`
      CREATE TABLE IF NOT EXISTS admin_ai_config (
        id              BIGSERIAL PRIMARY KEY,
        config_key      VARCHAR(100) NOT NULL UNIQUE,
        config_value    TEXT NOT NULL DEFAULT '',
        updated_by      BIGINT,
        updated_at      TIMESTAMPTZ NOT NULL DEFAULT NOW()
      )
    `);
  } catch (e) {
    console.warn("[daily-report] Table creation warning (may already exist):", e);
  }
}

interface DailyStats {
  newUsers: number;
  newRooms: number;
  newCommits: number;
  newMessages: number;
  activeUsers: number;
  topRoom: { id: string; name: string; messageCount: number } | null;
  topRoomMessages: { content: string; created_at: string }[];
}

interface AiConfig {
  ai_model: string;
  ai_api_key: string;
  ai_enabled: string;
  basic_api_url: string;
  smtp_host: string;
  smtp_port: string;
  smtp_username: string;
  smtp_password: string;
  smtp_from: string;
  smtp_tls: string;
  report_enabled: string;
}

// ─── Main handler ─────────────────────────────────────────────────────────────

export async function POST(req: NextRequest) {
  // Verify cron — accept internal marker OR secret from K8s CronJob
  const cronInternal = req.headers.get("x-cron-internal");
  const cronSecret = req.headers.get("x-cron-secret");
  const expectedSecret = process.env.DAILY_REPORT_CRON_SECRET;
  if (!cronInternal && (!expectedSecret || cronSecret !== expectedSecret)) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  try {
    // ── Ensure DB tables exist ─────────────────────────────────────────────────
    await ensureTablesExist();

    // ── Load config ────────────────────────────────────────────────────────────
    const configRows = await query<{ config_key: string; config_value: string }>(
      `SELECT config_key, config_value FROM admin_ai_config`
    );
    const config: Record<string, string> = {};
    for (const row of configRows.rows) {
      config[row.config_key] = row.config_value;
    }
    const cfg = config as unknown as AiConfig;

    if (cfg.report_enabled !== "true") {
      return NextResponse.json({ message: "report disabled, skipping" });
    }

    // ── Check recipients ────────────────────────────────────────────────────
    const recipients = await query(
      `SELECT email, name FROM internal_email_recipients WHERE is_active = true`
    );
    if (!recipients.rows.length) {
      return NextResponse.json({ message: "no recipients, skipping" });
    }

    // ── Collect daily stats ─────────────────────────────────────────────────
    const stats = await collectDailyStats();

    // ── Generate AI summary ──────────────────────────────────────────────────
    let aiSummary = "";
    if (cfg.ai_enabled === "true" && cfg.ai_api_key) {
      aiSummary = await generateAiSummary(
        stats,
        cfg.ai_model || "gpt-4o-mini",
        cfg.ai_api_key,
        cfg.basic_api_url || ""
      );
    }

    // ── Build email content ─────────────────────────────────────────────────
    const dateStr = new Date().toLocaleDateString("zh-CN", {
      year: "numeric", month: "2-digit", day: "2-digit",
    });
    const subject = `📊 每日平台报告 — ${dateStr}`;
    const htmlBody = buildHtmlReport(dateStr, stats, aiSummary);

    // ── Send emails ─────────────────────────────────────────────────────────
    const smtpConfigured =
      cfg.smtp_host && cfg.smtp_port && cfg.smtp_username && cfg.smtp_from;

    if (!smtpConfigured) {
      console.warn("[daily-report] SMTP not configured, email skipped");
      return NextResponse.json({
        message: "SMTP not configured, email skipped",
        stats: summarizeStats(stats),
      });
    }

    const sent = await sendEmail({
      host: cfg.smtp_host,
      port: parseInt(cfg.smtp_port || "587", 10),
      user: cfg.smtp_username,
      pass: cfg.smtp_password,
      from: cfg.smtp_from,
      tls: cfg.smtp_tls === "true",
      to: (recipients.rows as { email: string }[]).map(r => r.email),
      subject,
      html: htmlBody,
    });

    return NextResponse.json({
      sent,
      recipients: recipients.rows.length,
      stats: summarizeStats(stats),
      aiSummaryUsed: !!aiSummary,
    });
  } catch (e) {
    logError("[daily-report] Error:", e);
    return NextResponse.json({ error: String(e) }, { status: 500 });
  }
}

// ─── Stats collection ─────────────────────────────────────────────────────────

async function collectDailyStats(): Promise<DailyStats> {
  const today = new Date();
  today.setHours(0, 0, 0, 0);
  const todayStr = today.toISOString();

  const [userRow, roomRow, messageRow, activeUserRow, topRoomRow] = await Promise.all([
    // New users today
    query<{ count: string }>(
      `SELECT COUNT(*)::text as count FROM "user" WHERE created_at >= $1`,
      [todayStr]
    ),
    // New rooms today
    query<{ count: string }>(
      `SELECT COUNT(*)::text as count FROM room WHERE created_at >= $1`,
      [todayStr]
    ),
    // New messages today
    query<{ count: string }>(
      `SELECT COUNT(*)::text as count FROM room_message WHERE created_at >= $1`,
      [todayStr]
    ),
    // Active users today (users who sent messages)
    query<{ count: string }>(
      `SELECT COUNT(DISTINCT sender_id)::text as count
       FROM room_message WHERE created_at >= $1`,
      [todayStr]
    ),
    // Top room by message count today
    query<{ room: string; room_name: string; message_count: string }>(
      `SELECT rm.room, r.name as room_name, COUNT(*)::text as message_count
       FROM room_message rm
       JOIN room r ON r.id = rm.room
       WHERE rm.created_at >= $1
       GROUP BY rm.room, r.name
       ORDER BY COUNT(*) DESC
       LIMIT 1`,
      [todayStr]
    ),
  ]);

  const stats: DailyStats = {
    newUsers: parseInt(userRow.rows[0]?.count || "0", 10),
    newRooms: parseInt(roomRow.rows[0]?.count || "0", 10),
    newMessages: parseInt(messageRow.rows[0]?.count || "0", 10),
    activeUsers: parseInt(activeUserRow.rows[0]?.count || "0", 10),
    newCommits: 0, // filled below
    topRoom: topRoomRow.rows[0] ? {
      id: topRoomRow.rows[0].room,
      name: topRoomRow.rows[0].room_name,
      messageCount: parseInt(topRoomRow.rows[0].message_count || "0", 10),
    } : null,
    topRoomMessages: [],
  };

  // New commits today (git_commits table)
  try {
    const commitRow = await query<{ count: string }>(
      `SELECT COUNT(*)::text as count FROM git_commit WHERE committed_at >= $1`,
      [todayStr]
    );
    stats.newCommits = parseInt(commitRow.rows[0]?.count || "0", 10);
  } catch {
    // git_commit table might not exist yet
    stats.newCommits = 0;
  }

  // Fetch top room's recent messages for AI summary
  if (stats.topRoom) {
    try {
      const messages = await query<{ content: string; created_at: string }>(
        `SELECT content, created_at::text
         FROM room_message
         WHERE room = $1 AND created_at >= $2
         ORDER BY created_at DESC
         LIMIT 20`,
        [stats.topRoom.id, todayStr]
      );
      stats.topRoomMessages = messages.rows;
    } catch {
      stats.topRoomMessages = [];
    }
  }

  return stats;
}

// ─── AI Summary ──────────────────────────────────────────────────────────────

async function generateAiSummary(
  stats: DailyStats,
  model: string,
  apiKey: string,
  basicApiUrl: string
): Promise<string> {
  const systemPrompt = `你是一名平台运营分析师。请根据以下每日平台数据，生成一段简洁的中文总结（100-200字），分析今日平台的关键变化和亮点。注意：
1. 用专业但易懂的语言
2. 突出增长或异常数据
3. 如果有最活跃房间，给出简短评价
4. 结尾给出简短建议`;

  const topRoomContext = stats.topRoom
    ? `最活跃聊天室「${stats.topRoom.name}」今日发送 ${stats.topRoom.messageCount} 条消息。`
    : "今日无聊天室活动。";

  const userContext = stats.newUsers > 0
    ? `新增用户 ${stats.newUsers} 人，活跃用户 ${stats.activeUsers} 人。`
    : `今日新增用户较少（${stats.newUsers} 人），活跃用户 ${stats.activeUsers} 人。`;

  const userMessages = stats.topRoomMessages
    .slice(0, 5)
    .map((m, i) => `${i + 1}. ${m.content.slice(0, 150)}`)
    .join("\n");

  const userMessagesSection = stats.topRoomMessages.length > 0
    ? `\n\n最活跃房间「${stats.topRoom!.name}」最新消息样例：\n${userMessages}`
    : "";

  const userContent = `日期：${new Date().toLocaleDateString("zh-CN")}
平台数据：
- 新增用户：${stats.newUsers} 人
- 活跃用户：${stats.activeUsers} 人
- 新增聊天室：${stats.newRooms} 个
- 新增消息：${stats.newMessages} 条
- 新增代码提交：${stats.newCommits} 次
${topRoomContext}
${userMessagesSection}`;

  const baseUrl = basicApiUrl || "https://api.openai.com";
  const chatEndpoint = `${baseUrl.replace(/\/$/, "")}/v1/chat/completions`;

  try {
    const response = await fetch(chatEndpoint, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Authorization": `Bearer ${apiKey}`,
      },
      body: JSON.stringify({
        model,
        messages: [
          { role: "system", content: systemPrompt },
          { role: "user", content: userContent },
        ],
        max_tokens: 500,
        temperature: 0.7,
      }),
    });

    if (!response.ok) {
      const err = await response.text();
      console.warn("[daily-report] AI call failed:", response.status, err);
      return "";
    }

    const data = await response.json() as {
      choices?: { message?: { content?: string } }[];
    };
    return data.choices?.[0]?.message?.content?.trim() || "";
  } catch (e) {
    console.warn("[daily-report] AI call error:", e);
    return "";
  }
}

// ─── HTML Report Builder ──────────────────────────────────────────────────────

function buildHtmlReport(date: string, stats: DailyStats, aiSummary: string): string {
  const aiSection = aiSummary
    ? `<div style="background:#f0f9ff;border:1px solid #bae6fd;border-radius:8px;padding:16px;margin:16px 0">
        <div style="font-weight:600;color:#0369a1;margin-bottom:8px">🤖 AI 分析总结</div>
        <p style="margin:0;color:#0c4a6e;line-height:1.6">${aiSummary}</p>
       </div>`
    : `<div style="background:#fff7ed;border:1px solid #fed7aa;border-radius:8px;padding:16px;margin:16px 0;color:#9a3412">
        ⚠️ AI 分析未启用（请在设置中配置 AI 以获取每日自动分析）
       </div>`;

  const topRoomSection = stats.topRoom
    ? `<tr>
        <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">💬 最活跃聊天室</td>
        <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">
          <strong>${stats.topRoom.name}</strong> — ${stats.topRoom.messageCount} 条消息
        </td>
       </tr>`
    : `<tr>
        <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">💬 最活跃聊天室</td>
        <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb;color:#9ca3af">今日无聊天室活动</td>
       </tr>`;

  return `<!DOCTYPE html>
<html>
<head><meta charset="utf-8"></head>
<body style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;max-width:640px;margin:0 auto;padding:20px;background:#f9fafb">
  <div style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 3px rgba(0,0,0,0.1)">
    <div style="background:linear-gradient(135deg,#667eea,#764ba2);padding:24px 32px">
      <div style="color:rgba(255,255,255,0.9);font-size:13px;margin-bottom:4px">每日平台报告</div>
      <h1 style="color:#fff;margin:0;font-size:22px">${date}</h1>
    </div>

    ${aiSection}

    <div style="padding:0 24px 24px">
      <h2 style="font-size:15px;color:#374151;margin:16px 0 8px;border-bottom:2px solid #e5e7eb;padding-bottom:8px">📈 今日数据</h2>
      <table style="width:100%;border-collapse:collapse;font-size:14px">
        <tr style="background:#f9fafb">
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">👥 新增用户</td>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:600;color:#059669">${stats.newUsers} 人</td>
        </tr>
        <tr>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">🟢 活跃用户</td>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:600">${stats.activeUsers} 人</td>
        </tr>
        <tr style="background:#f9fafb">
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">🏠 新增聊天室</td>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:600;color:#7c3aed">${stats.newRooms} 个</td>
        </tr>
        <tr>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">💬 聊天室消息</td>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:600;color:#2563eb">${stats.newMessages} 条</td>
        </tr>
        <tr style="background:#f9fafb">
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb">🔧 代码提交</td>
          <td style="padding:10px 16px;border-bottom:1px solid #e5e7eb;text-align:right;font-weight:600">${stats.newCommits} 次</td>
        </tr>
        ${topRoomSection}
      </table>

      <div style="margin-top:24px;padding:16px;background:#f9fafb;border-radius:8px;font-size:12px;color:#9ca3af">
        此报告由系统自动生成，如需修改收件人或 AI 设置，请联系平台管理员。
      </div>
    </div>
  </div>
</body>
</html>`;
}

// ─── Email Sender (direct SMTP) ───────────────────────────────────────────────

async function sendEmail(opts: {
  host: string; port: number; user: string; pass: string;
  from: string; tls: boolean;
  to: string[]; subject: string; html: string;
}): Promise<number> {
  // Use nodemailer-style SMTP (via built-in tls net module)
  const { host, port, user, pass, from, tls, to, subject, html } = opts;

  // Simple SMTP client using Node.js built-ins
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  const net = await import("node:net") as any;
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  const tlsMod = await import("node:tls") as any;
  // eslint-disable-next-line @typescript-eslint/no-require-imports
  const cryptoMod = await import("node:crypto") as any;

  function b64(str: string): string {
    return Buffer.from(str).toString("base64");
  }

  let sentCount = 0;

  for (const recipient of to) {
    try {
      const socket = tls
        ? net.createSecureSocket({ host, port, servername: host })
        : net.createSocket({ host, port });

      await new Promise<void>((res, rej) => {
        const timeout = setTimeout(() => { socket.destroy(); rej(new Error("timeout")); }, 30000);
        const commands: string[] = [];
        let step = 0;

        socket.on("data", (chunk: Buffer) => {
          const lines = chunk.toString().split("\r\n");
          for (const line of lines) {
            commands.push(line);
            const code = line.slice(0, 3);
            if (code === "220" && step === 0) { step = 1; socket.write(`EHLO localhost\r\n`); }
            else if (code === "250" && step === 1) {
              step = 2;
              socket.write(`AUTH LOGIN\r\n`);
            } else if (code === "334" && step === 2) {
              step = 3;
              socket.write(b64(user) + "\r\n");
            } else if (code === "334" && step === 3) {
              step = 4;
              socket.write(b64(pass) + "\r\n");
            } else if (code === "235" && step === 4) {
              step = 5;
              socket.write(`MAIL FROM:<${from}>\r\n`);
            } else if (code === "250" && step === 5) {
              step = 6;
              socket.write(`RCPT TO:<${recipient}>\r\n`);
            } else if (code === "250" && step === 6) {
              step = 7;
              socket.write(`DATA\r\n`);
            } else if (code === "354" && step === 7) {
              step = 8;
              const msgId = `<${cryptoMod.randomBytes(8).toString("hex")}@daily-report>`;
              const msg = [
                `From: ${from}`,
                `To: ${recipient}`,
                `Subject: =?utf-8?B?${b64(subject)}?=`,
                "MIME-Version: 1.0",
                "Content-Type: text/html; charset=utf-8",
                `Message-ID: ${msgId}`,
                `Date: ${new Date().toUTCString()}`,
                "",
                html,
                ".",
              ].join("\r\n");
              socket.write(msg + "\r\n");
            } else if (code === "250" && step === 8) {
              step = 9;
              socket.write("QUIT\r\n");
              clearTimeout(timeout);
              res();
            }
          }
        });

        socket.on("error", (e: Error) => { clearTimeout(timeout); rej(e); });
        socket.on("close", () => { clearTimeout(timeout); if (step < 9) rej(new Error("connection closed")); });

        socket.write(`HELO localhost\r\n`);
      });

      sentCount++;
      console.log(`[daily-report] Sent to ${recipient}`);
    } catch (e) {
      logError(`[daily-report] Failed to send to ${recipient}:`, e);
    }
  }

  return sentCount;
}

// ─── Helpers ─────────────────────────────────────────────────────────────────

function summarizeStats(s: DailyStats) {
  return {
    newUsers: s.newUsers,
    newRooms: s.newRooms,
    newMessages: s.newMessages,
    newCommits: s.newCommits,
    activeUsers: s.activeUsers,
    topRoom: s.topRoom?.name || null,
    topRoomMessages: s.topRoomMessages.length,
  };
}
