import type { Metadata } from "next";
import Link from "next/link";
import ConvertLeadButton from "./ConvertLeadButton";
import AssignLeadButton from "./AssignLeadButton";
import CustomerAdminShell from "../../CustomerAdminShell";
import { cookies } from "next/headers";
import { notFound, redirect } from "next/navigation";

import { prisma } from "@/lib/prisma";
import { AUTH_COOKIE_NAME } from "@/lib/auth/constants";
import {
  hashSessionToken,
  isValidSessionTokenFormat,
} from "@/lib/auth/session-token";
import {
  hasPermission,
  loadAuthorizationForUser,
} from "@/lib/auth/authorization";

export const metadata: Metadata = {
  title: "Lead Details | Teja Technology CRM",
  robots: {
    index: false,
    follow: false,
  },
};

export const dynamic = "force-dynamic";

type PageProps = {
  params: Promise<{ leadCode: string }>;
};

function show(value: string | null | undefined): string {
  return value?.trim() || "—";
}

function showDate(value: Date | null): string {
  return value
    ? value.toLocaleString("en-IN", {
        dateStyle: "medium",
        timeStyle: "short",
        timeZone: "Asia/Kolkata",
      })
    : "—";
}

export default async function AdminLeadDetailsPage({
  params,
}: PageProps) {
  const cookieStore = await cookies();
  const token = cookieStore.get(AUTH_COOKIE_NAME)?.value;

  if (!token || !isValidSessionTokenFormat(token)) {
    redirect("/admin/login");
  }

  const session = await prisma.authSession.findUnique({
    where: { tokenHash: hashSessionToken(token) },
    select: {
      userId: true,
      expiresAt: true,
      revokedAt: true,
    },
  });

  if (
    !session ||
    session.revokedAt !== null ||
    session.expiresAt.getTime() <= Date.now()
  ) {
    redirect("/admin/login");
  }

  const authorization =
    await loadAuthorizationForUser(session.userId);

  if (
    !authorization ||
    authorization.status !== "ACTIVE" ||
    !authorization.roles.includes("SUPER_ADMIN")
  ) {
    redirect("/admin/login");
  }

  if (authorization.mustChangePassword) {
    redirect("/admin/change-password");
  }

  if (!hasPermission(authorization, "LEAD_VIEW")) {
    redirect("/admin");
  }

  const { leadCode } = await params;

  if (!/^TTL-[A-F0-9]{20}$/.test(leadCode)) {
    notFound();
  }

  const lead = await prisma.lead.findUnique({
    where: { leadCode },
    select: {
      id: true,
      leadCode: true,
      name: true,
      companyName: true,
      email: true,
      phone: true,
      service: true,
      budget: true,
      message: true,
      source: true,
      status: true,
      nextFollowUpAt: true,
      convertedAt: true,
      createdAt: true,
      updatedAt: true,
      assignedTo: {
        select: { name: true, userCode: true },
      },
      createdBy: {
        select: { name: true, userCode: true },
      },
      client: {
        select: { clientCode: true, name: true },
      },
    },
  });

  if (!lead) {
    notFound();
  }


  // ADMIN_LEAD_ACTIVITY_STEP102
  // Admin authentication and LEAD_VIEW permission were checked above.
  const activity = await prisma.auditLog.findMany({
    where: {
      module: "CRM",
      entityType: "Lead",
      entityId: lead.id,
      action: {
        in: [
          "LEAD_NOTE_ADDED",
          "LEAD_STATUS_UPDATED",
          "LEAD_FOLLOW_UP_UPDATED",
          "LEAD_ASSIGNED",
          "LEAD_CONVERTED",
        ],
      },
    },
    orderBy: [
      { createdAt: "desc" },
      { id: "desc" },
    ],
    take: 50,
    select: {
      id: true,
      action: true,
      createdAt: true,
      oldValues: true,
      newValues: true,
      user: {
        select: {
          name: true,
          userCode: true,
        },
      },
    },
  });

  function readActivityField(
    value: unknown,
    key: string,
  ): string | null {
    if (
      !value ||
      typeof value !== "object" ||
      Array.isArray(value)
    ) {
      return null;
    }

    const field = (value as Record<string, unknown>)[key];

    return typeof field === "string" ? field : null;
  }

  function formatFollowUpDate(value: string | null): string {
    if (!value) return "Not scheduled";

    const parsed = new Date(value);

    if (!Number.isFinite(parsed.getTime())) {
      return "Updated";
    }

    return new Intl.DateTimeFormat("en-IN", {
      timeZone: "UTC",
      day: "2-digit",
      month: "short",
      year: "numeric",
    }).format(parsed);
  }

  const canAssign =
    hasPermission(authorization, "LEAD_ASSIGN") &&
    ![
      "CONVERTED",
      "DUPLICATE",
      "LOST",
      "CLOSED",
      "NOT_INTERESTED",
    ].includes(lead.status);

  const eligibleStaff = canAssign
    ? await prisma.user.findMany({
        where: {
          status: "ACTIVE",
          roles: {
            some: {
              role: {
                code: {
                  in: ["ADMIN", "SALES_CRM"],
                },
              },
            },
          },
        },
        orderBy: { name: "asc" },
        take: 200,
        select: {
          id: true,
          userCode: true,
          name: true,
          roles: {
            select: {
              role: {
                select: {
                  code: true,
                  permissions: {
                    select: {
                      permission: {
                        select: { code: true },
                      },
                    },
                  },
                },
              },
            },
          },
        },
      })
    : [];

  const assignableStaff = eligibleStaff
    .filter((user) => {
      const permissions = new Set(
        user.roles.flatMap(({ role }) =>
          role.permissions.map(({ permission }) => permission.code),
        ),
      );

      return (
        permissions.has("LEAD_VIEW") &&
        permissions.has("LEAD_UPDATE")
      );
    })
    .map((user) => ({
      userCode: user.userCode,
      name: user.name,
    }));

  const canConvert =
    hasPermission(authorization, "LEAD_CONVERT") &&
    hasPermission(authorization, "CLIENT_CREATE") &&
    lead.client === null &&
    lead.convertedAt === null &&
    ![
      "CONVERTED",
      "DUPLICATE",
      "LOST",
      "CLOSED",
      "NOT_INTERESTED",
    ].includes(lead.status);

  const details: Array<[string, string]> = [
    ["Lead Code", lead.leadCode],
    ["Name", lead.name],
    ["Company", show(lead.companyName)],
    ["Email", show(lead.email)],
    ["Phone", show(lead.phone)],
    ["Service", show(lead.service)],
    ["Budget (INR)", lead.budget?.toString() ?? "—"],
    ["Source", lead.source],
    ["Status", lead.status],
    [
      "Assigned To",
      lead.assignedTo
        ? `${lead.assignedTo.name} (${lead.assignedTo.userCode})`
        : "Unassigned",
    ],
    [
      "Created By",
      lead.createdBy
        ? `${lead.createdBy.name} (${lead.createdBy.userCode})`
        : "Website / Not assigned",
    ],
    ["Next Follow-up", showDate(lead.nextFollowUpAt)],
    ["Converted At", showDate(lead.convertedAt)],
    [
      "Linked Client",
      lead.client
        ? `${lead.client.name} (${lead.client.clientCode})`
        : "Not converted",
    ],
    ["Created At", showDate(lead.createdAt)],
    ["Updated At", showDate(lead.updatedAt)],
  ];

  return (
    <CustomerAdminShell>
      <main className="min-h-[75vh] w-full min-w-0 bg-[var(--soft)] px-4 py-7 sm:px-6 lg:px-8">
      <div className="mx-auto w-full max-w-7xl space-y-6">
        <div className="mb-8 flex flex-wrap items-start justify-between gap-4">
          <div>
            <p className="mb-2 text-xs font-bold uppercase tracking-[0.18em] text-[var(--blue)]">
              Teja Technology CRM
            </p>
            <h1 className="text-3xl font-bold text-[var(--navy)]">
              Lead Details
            </h1>
            <p className="mt-2 text-sm text-[var(--muted)]">
              Reference: {lead.leadCode}
            </p>
          </div>

          <div className="flex flex-wrap items-center gap-3">
            {canConvert && (
              <ConvertLeadButton
                leadCode={lead.leadCode}
              />
            )}

            {lead.client && (
              <Link
                href={`/admin/customers/${encodeURIComponent(
                  lead.client.clientCode,
                )}`}
                className="rounded-xl bg-[var(--blue)] px-5 py-3 text-sm font-semibold text-white"
              >
                View Customer
              </Link>
            )}

            <Link
              href="/admin/leads"
              className="rounded-xl border border-[var(--line)] bg-white px-5 py-3 text-sm font-semibold text-[var(--navy)]"
            >
              Back to Leads
            </Link>
          </div>
        </div>

        {canAssign && (
          <section className="mb-6 rounded-2xl border border-[var(--line)] bg-white p-6 shadow-sm">
            <h2 className="text-lg font-bold text-[var(--navy)]">
              Assign Lead to Staff
            </h2>

            <p className="mt-2 text-sm text-[var(--muted)]">
              Select an active ADMIN or SALES_CRM staff member
              with Lead View and Lead Update permissions.
            </p>

            <div className="mt-5">
              <AssignLeadButton
                leadCode={lead.leadCode}
                currentAssigneeCode={
                  lead.assignedTo?.userCode ?? null
                }
                staff={assignableStaff}
              />
            </div>
          </section>
        )}

        <section className="rounded-2xl border border-[var(--line)] bg-white p-6 shadow-sm">
          <dl className="grid gap-6 sm:grid-cols-2 xl:grid-cols-3">
            {details.map(([label, value]) => (
              <div key={label} className="min-w-0">
                <dt className="text-xs font-semibold uppercase tracking-wide text-[var(--muted)]">
                  {label}
                </dt>
                <dd className="mt-2 break-words text-sm font-medium text-[var(--navy)]">
                  {value}
                </dd>
              </div>
            ))}
          </dl>
        </section>

        <section className="mt-6 rounded-2xl border border-[var(--line)] bg-white p-6 shadow-sm">
          <h2 className="text-lg font-bold text-[var(--navy)]">
            Customer Requirement
          </h2>
          <p className="mt-4 whitespace-pre-wrap break-words text-sm leading-7 text-[var(--navy)]">
            {show(lead.message)}
          </p>
        </section>

        {/* ADMIN_LEAD_ACTIVITY_STEP102 */}
        <section className="mt-6 rounded-2xl border border-[var(--line)] bg-white p-6 shadow-sm">
          <div className="flex flex-wrap items-center justify-between gap-3">
            <div>
              <h2 className="text-lg font-bold text-[var(--navy)]">
                Lead Activity History
              </h2>

              <p className="mt-2 text-sm text-[var(--muted)]">
                Latest 50 recorded notes, status changes, follow-ups
                and assignment updates for this lead.
              </p>
            </div>

            <span className="rounded-lg bg-[var(--soft)] px-3 py-2 text-xs font-semibold text-[var(--navy)]">
              {activity.length} activities
            </span>
          </div>

          {activity.length === 0 ? (
            <p className="mt-6 text-sm text-[var(--muted)]">
              No recorded activity for this lead yet.
            </p>
          ) : (
            <div className="mt-5 divide-y divide-[var(--line)]">
              {activity.map((entry) => {
                const note = readActivityField(
                  entry.newValues,
                  "note",
                );

                const oldStatus = readActivityField(
                  entry.oldValues,
                  "status",
                );

                const newStatus = readActivityField(
                  entry.newValues,
                  "status",
                );

                const oldFollowUp = readActivityField(
                  entry.oldValues,
                  "nextFollowUpAt",
                );

                const newFollowUp = readActivityField(
                  entry.newValues,
                  "nextFollowUpAt",
                );

                const title =
                  entry.action === "LEAD_NOTE_ADDED"
                    ? "Note Added"
                    : entry.action === "LEAD_STATUS_UPDATED"
                      ? "Status Updated"
                      : entry.action === "LEAD_FOLLOW_UP_UPDATED"
                        ? "Follow-up Updated"
                        : entry.action === "LEAD_ASSIGNED"
                          ? "Lead Assigned"
                          : entry.action === "LEAD_CONVERTED"
                            ? "Lead Converted"
                            : "Lead Activity";

                return (
                  <article key={entry.id} className="py-5">
                    <div className="flex flex-wrap items-start justify-between gap-3">
                      <h3 className="text-sm font-bold text-[var(--navy)]">
                        {title}
                      </h3>

                      <time className="text-xs text-[var(--muted)]">
                        {showDate(entry.createdAt)}
                      </time>
                    </div>

                    <p className="mt-2 text-xs text-[var(--muted)]">
                      By {entry.user?.name ?? "System"}
                      {entry.user?.userCode
                        ? ` (${entry.user.userCode})`
                        : ""}
                    </p>

                    {note && (
                      <p className="mt-3 whitespace-pre-wrap break-words rounded-xl bg-[var(--soft)] px-4 py-3 text-sm leading-6 text-[var(--navy)]">
                        {note}
                      </p>
                    )}

                    {entry.action === "LEAD_STATUS_UPDATED" &&
                      newStatus && (
                        <p className="mt-3 text-sm text-[var(--navy)]">
                          {oldStatus
                            ? `${oldStatus} → ${newStatus}`
                            : newStatus}
                        </p>
                      )}

                    {entry.action === "LEAD_FOLLOW_UP_UPDATED" &&
                      newFollowUp && (
                        <p className="mt-3 text-sm text-[var(--navy)]">
                          {formatFollowUpDate(oldFollowUp)}
                          {" → "}
                          {formatFollowUpDate(newFollowUp)}
                        </p>
                      )}
                  </article>
                );
              })}
            </div>
          )}
        </section>

      </div>
      </main>
    </CustomerAdminShell>
  );
}
