import prisma from "@/lib/prisma";
import { auth } from "@/lib/auth";
import { redirect } from "next/navigation";
import Link from "next/link";
import { BanRingButton } from "./FraudActions";

interface SameIpRow {
  ip_address: string;
  account_count: bigint;
  user_ids: number[];
}

interface DuplicateStatusRow {
  status: string;
  dup_count: bigint;
  user_ids: number[];
}

interface DuplicatePhotoRow {
  profile_photo: string;
  dup_count: bigint;
  user_ids: number[];
}

interface RapidRegRow {
  user1_id: number;
  user2_id: number;
  ip_address: string;
  user1: string | null;
  user2: string | null;
  created1: Date;
  created2: Date;
}

function SeverityBadge({ level }: { level: "critical" | "high" | "medium" }) {
  const styles = {
    critical: "bg-red-500/20 text-red-400 border-red-500/30",
    high: "bg-orange-500/20 text-orange-400 border-orange-500/30",
    medium: "bg-yellow-500/20 text-yellow-400 border-yellow-500/30",
  };
  return (
    <span
      className={`px-2 py-0.5 rounded text-xs font-semibold uppercase border ${styles[level]}`}
    >
      {level}
    </span>
  );
}

function UserLink({ id, username }: { id: number; username?: string | null }) {
  return (
    <Link
      href={`/admin/users/${id}`}
      className="text-primary hover:text-primary-light underline underline-offset-2 text-sm"
    >
      {username || `User #${id}`}
    </Link>
  );
}

export default async function FraudDetectionPage() {
  const session = await auth();
  if (!session?.user || session.user.userType !== "admin") {
    redirect("/login");
  }

  // Run all fraud detection queries in parallel
  let sameIpResults: SameIpRow[] = [];
  let duplicateStatusResults: DuplicateStatusRow[] = [];
  let duplicatePhotoResults: DuplicatePhotoRow[] = [];
  let rapidRegResults: RapidRegRow[] = [];

  const errors: string[] = [];

  // Query 1: Same IP registrations (3+ accounts within last 30 days)
  try {
    sameIpResults = await prisma.$queryRawUnsafe<SameIpRow[]>(`
      SELECT ip_address, COUNT(*) as account_count, array_agg(id) as user_ids
      FROM users
      WHERE ip_address IS NOT NULL AND created_at > NOW() - INTERVAL '30 days'
      GROUP BY ip_address HAVING COUNT(*) >= 3
      ORDER BY account_count DESC LIMIT 50
    `);
  } catch (e) {
    errors.push(`Same IP query failed: ${e instanceof Error ? e.message : "Unknown error"}`);
  }

  // Query 2: Duplicate status text (used as bio/about)
  try {
    duplicateStatusResults = await prisma.$queryRawUnsafe<DuplicateStatusRow[]>(`
      SELECT status, COUNT(*) as dup_count, array_agg(id) as user_ids
      FROM users
      WHERE status IS NOT NULL AND LENGTH(status) > 50
      GROUP BY status HAVING COUNT(*) > 1
      ORDER BY dup_count DESC LIMIT 50
    `);
  } catch (e) {
    errors.push(`Duplicate status query failed: ${e instanceof Error ? e.message : "Unknown error"}`);
  }

  // Query 3: Same profile photo filename
  try {
    duplicatePhotoResults = await prisma.$queryRawUnsafe<DuplicatePhotoRow[]>(`
      SELECT profile_photo, COUNT(*) as dup_count, array_agg(id) as user_ids
      FROM users
      WHERE profile_photo IS NOT NULL
      GROUP BY profile_photo HAVING COUNT(*) > 1
      ORDER BY dup_count DESC LIMIT 50
    `);
  } catch (e) {
    errors.push(`Duplicate photo query failed: ${e instanceof Error ? e.message : "Unknown error"}`);
  }

  // Query 4: Rapid registrations (same IP, within 5 minutes)
  try {
    rapidRegResults = await prisma.$queryRawUnsafe<RapidRegRow[]>(`
      SELECT a.id as user1_id, b.id as user2_id, a.ip_address,
             a.username as user1, b.username as user2,
             a.created_at as created1, b.created_at as created2
      FROM users a JOIN users b ON a.ip_address = b.ip_address AND a.id < b.id
      WHERE a.ip_address IS NOT NULL
        AND ABS(EXTRACT(EPOCH FROM a.created_at - b.created_at)) < 300
      ORDER BY a.created_at DESC LIMIT 50
    `);
  } catch (e) {
    errors.push(`Rapid registration query failed: ${e instanceof Error ? e.message : "Unknown error"}`);
  }

  // Fetch usernames for IP clusters
  const allIpUserIds = sameIpResults.flatMap((r) => r.user_ids);
  const allPhotoUserIds = duplicatePhotoResults.flatMap((r) => r.user_ids);
  const allStatusUserIds = duplicateStatusResults.flatMap((r) => r.user_ids);
  const allUserIds = [...new Set([...allIpUserIds, ...allPhotoUserIds, ...allStatusUserIds])];

  let usernameMap: Record<number, string> = {};
  if (allUserIds.length > 0) {
    try {
      const users = await prisma.user.findMany({
        where: { id: { in: allUserIds } },
        select: { id: true, username: true, banned_at: true },
      });
      usernameMap = Object.fromEntries(
        users.map((u) => [u.id, u.username || `User #${u.id}`])
      );
    } catch {
      // Graceful fallback — IDs will be shown instead
    }
  }

  // Calculate summary stats
  const totalClusters =
    sameIpResults.length +
    duplicateStatusResults.length +
    duplicatePhotoResults.length;
  const criticalCount = sameIpResults.filter(
    (r) => Number(r.account_count) >= 5
  ).length;
  const rapidPairCount = rapidRegResults.length;

  return (
    <div className="space-y-8">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Fraud Ring Detection</h1>
          <p className="text-text-muted text-sm mt-1">
            Automated analysis of coordinated account creation patterns
          </p>
        </div>
      </div>

      {/* Errors */}
      {errors.length > 0 && (
        <div className="bg-red-500/10 border border-red-500/30 rounded-lg p-4">
          <h3 className="text-red-400 font-semibold text-sm mb-2">Query Errors</h3>
          {errors.map((err, i) => (
            <p key={i} className="text-red-300 text-xs">
              {err}
            </p>
          ))}
        </div>
      )}

      {/* Summary Stats */}
      <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
        <div className="bg-surface rounded-lg p-4 border border-surface-light">
          <p className="text-text-muted text-xs uppercase tracking-wider">
            Suspicious Clusters
          </p>
          <p className="text-2xl font-bold mt-1">{totalClusters}</p>
        </div>
        <div className="bg-surface rounded-lg p-4 border border-red-500/30">
          <p className="text-red-400 text-xs uppercase tracking-wider">
            Critical (5+ same IP)
          </p>
          <p className="text-2xl font-bold mt-1 text-red-400">{criticalCount}</p>
        </div>
        <div className="bg-surface rounded-lg p-4 border border-orange-500/30">
          <p className="text-orange-400 text-xs uppercase tracking-wider">
            Duplicate Photos
          </p>
          <p className="text-2xl font-bold mt-1 text-orange-400">
            {duplicatePhotoResults.length}
          </p>
        </div>
        <div className="bg-surface rounded-lg p-4 border border-yellow-500/30">
          <p className="text-yellow-400 text-xs uppercase tracking-wider">
            Rapid Reg Pairs
          </p>
          <p className="text-2xl font-bold mt-1 text-yellow-400">{rapidPairCount}</p>
        </div>
      </div>

      {/* Section 1: Same IP Registrations */}
      <section>
        <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
          Same IP Registrations
          <span className="text-text-muted text-sm font-normal">
            (3+ accounts from one IP in 30 days)
          </span>
        </h2>
        {sameIpResults.length === 0 ? (
          <div className="bg-surface rounded-lg p-6 text-center text-text-muted text-sm">
            No suspicious IP clusters found.
          </div>
        ) : (
          <div className="space-y-3">
            {sameIpResults.map((row, i) => {
              const count = Number(row.account_count);
              const severity = count >= 5 ? "critical" : "medium";
              return (
                <div
                  key={i}
                  className="bg-surface rounded-lg p-4 border border-surface-light flex flex-col sm:flex-row sm:items-center gap-3"
                >
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 mb-2">
                      <SeverityBadge level={severity} />
                      <span className="text-sm font-mono text-text-muted">
                        {row.ip_address}
                      </span>
                      <span className="text-xs text-text-muted">
                        ({count} accounts)
                      </span>
                    </div>
                    <div className="flex flex-wrap gap-2">
                      {row.user_ids.map((uid) => (
                        <UserLink
                          key={uid}
                          id={uid}
                          username={usernameMap[uid]}
                        />
                      ))}
                    </div>
                  </div>
                  <BanRingButton
                    userIds={row.user_ids}
                    label={`Same IP: ${row.ip_address}`}
                  />
                </div>
              );
            })}
          </div>
        )}
      </section>

      {/* Section 2: Duplicate Profile Photos */}
      <section>
        <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
          Duplicate Profile Photos
          <span className="text-text-muted text-sm font-normal">
            (same photo filename across accounts)
          </span>
        </h2>
        {duplicatePhotoResults.length === 0 ? (
          <div className="bg-surface rounded-lg p-6 text-center text-text-muted text-sm">
            No duplicate profile photos found.
          </div>
        ) : (
          <div className="space-y-3">
            {duplicatePhotoResults.map((row, i) => (
              <div
                key={i}
                className="bg-surface rounded-lg p-4 border border-surface-light flex flex-col sm:flex-row sm:items-center gap-3"
              >
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-2">
                    <SeverityBadge level="high" />
                    <span className="text-sm text-text-muted truncate max-w-xs">
                      {row.profile_photo}
                    </span>
                    <span className="text-xs text-text-muted">
                      ({Number(row.dup_count)} accounts)
                    </span>
                  </div>
                  <div className="flex flex-wrap gap-2">
                    {row.user_ids.map((uid) => (
                      <UserLink
                        key={uid}
                        id={uid}
                        username={usernameMap[uid]}
                      />
                    ))}
                  </div>
                </div>
                <BanRingButton
                  userIds={row.user_ids}
                  label={`Same photo: ${row.profile_photo}`}
                />
              </div>
            ))}
          </div>
        )}
      </section>

      {/* Section 3: Duplicate Status/Bio Text */}
      <section>
        <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
          Duplicate Bio / Status Text
          <span className="text-text-muted text-sm font-normal">
            (identical text across accounts, 50+ chars)
          </span>
        </h2>
        {duplicateStatusResults.length === 0 ? (
          <div className="bg-surface rounded-lg p-6 text-center text-text-muted text-sm">
            No duplicate status text found.
          </div>
        ) : (
          <div className="space-y-3">
            {duplicateStatusResults.map((row, i) => (
              <div
                key={i}
                className="bg-surface rounded-lg p-4 border border-surface-light flex flex-col sm:flex-row sm:items-center gap-3"
              >
                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 mb-2">
                    <SeverityBadge level="medium" />
                    <span className="text-xs text-text-muted">
                      ({Number(row.dup_count)} accounts)
                    </span>
                  </div>
                  <p className="text-xs text-text-muted bg-surface-light rounded px-2 py-1 mb-2 line-clamp-2">
                    &ldquo;{row.status}&rdquo;
                  </p>
                  <div className="flex flex-wrap gap-2">
                    {row.user_ids.map((uid) => (
                      <UserLink
                        key={uid}
                        id={uid}
                        username={usernameMap[uid]}
                      />
                    ))}
                  </div>
                </div>
                <BanRingButton
                  userIds={row.user_ids}
                  label="Duplicate bio text"
                />
              </div>
            ))}
          </div>
        )}
      </section>

      {/* Section 4: Rapid Registrations */}
      <section>
        <h2 className="text-lg font-semibold mb-3 flex items-center gap-2">
          Rapid Registrations
          <span className="text-text-muted text-sm font-normal">
            (same IP, within 5 minutes of each other)
          </span>
        </h2>
        {rapidRegResults.length === 0 ? (
          <div className="bg-surface rounded-lg p-6 text-center text-text-muted text-sm">
            No rapid registration pairs found.
          </div>
        ) : (
          <div className="bg-surface rounded-lg border border-surface-light overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-surface-light text-text-muted text-xs uppercase">
                  <th className="px-4 py-3 text-left">Severity</th>
                  <th className="px-4 py-3 text-left">IP Address</th>
                  <th className="px-4 py-3 text-left">Account 1</th>
                  <th className="px-4 py-3 text-left">Account 2</th>
                  <th className="px-4 py-3 text-left">Time Gap</th>
                  <th className="px-4 py-3 text-right">Action</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-surface-light">
                {rapidRegResults.map((row, i) => {
                  const gapSeconds = Math.abs(
                    (new Date(row.created1).getTime() -
                      new Date(row.created2).getTime()) /
                      1000
                  );
                  const gapLabel =
                    gapSeconds < 60
                      ? `${Math.round(gapSeconds)}s`
                      : `${Math.round(gapSeconds / 60)}m ${Math.round(gapSeconds % 60)}s`;
                  return (
                    <tr key={i} className="hover:bg-surface-light/50">
                      <td className="px-4 py-3">
                        <SeverityBadge
                          level={gapSeconds < 60 ? "critical" : "high"}
                        />
                      </td>
                      <td className="px-4 py-3 font-mono text-text-muted text-xs">
                        {row.ip_address}
                      </td>
                      <td className="px-4 py-3">
                        <UserLink id={row.user1_id} username={row.user1} />
                      </td>
                      <td className="px-4 py-3">
                        <UserLink id={row.user2_id} username={row.user2} />
                      </td>
                      <td className="px-4 py-3 text-text-muted text-xs">
                        {gapLabel}
                      </td>
                      <td className="px-4 py-3 text-right">
                        <BanRingButton
                          userIds={[row.user1_id, row.user2_id]}
                          label={`Rapid reg from ${row.ip_address}`}
                        />
                      </td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          </div>
        )}
      </section>
    </div>
  );
}
