import { notFound, redirect } from "next/navigation";
import { format } from "date-fns";
import { Layers, Users } from "lucide-react";
import { inArray } from "drizzle-orm";
import { db } from "@db/client";
import { events, ticketTypes } from "@db/schema";
import { getDashboardUser } from "@/lib/view-as";
import { getMySegmentById, resolveSegment } from "@db/queries/segments";
import type { CustomerSegmentRow } from "@/lib/types";
import { formatPrice } from "@/lib/format";
import { PageHeader, Card, StatCard, TableShell, EmptyState } from "@/components/ui";

export const metadata = { title: "Segment · Dashboard" };

function describeCondition(
  condition: CustomerSegmentRow["filter"]["conditions"][number],
  eventTitleById: Map<string, string>,
  ticketTypeNameById: Map<string, string>
): string {
  if (condition.type === "min_spent") {
    return `Spent at least ${formatPrice(condition.cents, "kes")}`;
  }
  if (condition.type === "bought_ticket_type") {
    const names = condition.ticket_type_ids.map((id) => ticketTypeNameById.get(id) ?? "a removed ticket type");
    return `Bought ${names.join(" or ")} for ${eventTitleById.get(condition.event_id) ?? "an unknown event"}`;
  }
  return `Bought a ticket to ${eventTitleById.get(condition.event_id) ?? "an unknown event"}`;
}

export default async function SegmentDetailPage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const { user } = await getDashboardUser();
  if (!user) redirect("/login");

  const row = await getMySegmentById(user.id, id);
  if (!row) notFound();

  const eventIds = row.filter.conditions.flatMap((c) =>
    c.type === "bought_event" || c.type === "bought_ticket_type" ? [c.event_id] : []
  );
  const typeIds = row.filter.conditions.flatMap((c) => (c.type === "bought_ticket_type" ? c.ticket_type_ids : []));
  const typeRows = typeIds.length
    ? await db.select({ id: ticketTypes.id, name: ticketTypes.name }).from(ticketTypes).where(inArray(ticketTypes.id, typeIds))
    : [];
  const ticketTypeNameById = new Map(typeRows.map((t) => [t.id, t.name]));
  const eventRows = eventIds.length
    ? await db.select({ id: events.id, title: events.title }).from(events).where(inArray(events.id, eventIds))
    : [];
  const eventTitleById = new Map(eventRows.map((e) => [e.id, e.title]));

  const customers = await resolveSegment(user.id, row.filter);

  return (
    <div className="space-y-8">
      <PageHeader
        icon={Layers}
        title={row.name}
        description={`Created ${format(new Date(row.created_at), "PP")}`}
      />

      <section className="grid grid-cols-2 sm:grid-cols-4 gap-3">
        <StatCard icon={Users} label="Customers" value={customers.length.toString()} />
      </section>

      <Card>
        <p className="mb-2 text-sm font-medium text-be-text">
          Match {row.filter.match === "any" ? "any" : "all"} of:
        </p>
        <ul className="list-disc space-y-1 pl-5 text-sm text-be-muted">
          {row.filter.conditions.map((c, i) => (
            <li key={i}>{describeCondition(c, eventTitleById, ticketTypeNameById)}</li>
          ))}
        </ul>
      </Card>

      <section className="space-y-3">
        <h2 className="text-lg font-medium text-be-text">Matching customers</h2>
        {customers.length === 0 ? (
          <EmptyState
            icon={Users}
            title="No matches yet"
            body="No customer currently satisfies every rule in this segment."
          />
        ) : (
          <TableShell>
            <thead>
              <tr>
                <th>Name</th>
                <th>Email</th>
                <th className="text-right">Orders</th>
                <th className="text-right">Total spent</th>
              </tr>
            </thead>
            <tbody>
              {customers.map((c) => (
                <tr key={c.id}>
                  <td className="font-medium text-be-text">{c.full_name || "—"}</td>
                  <td className="text-be-muted">{c.email}</td>
                  <td className="text-right tabular-nums text-be-text">{c.total_orders}</td>
                  <td className="text-right tabular-nums text-be-text">
                    {formatPrice(c.total_spent_cents, "kes")}
                  </td>
                </tr>
              ))}
            </tbody>
          </TableShell>
        )}
      </section>
    </div>
  );
}
