import { getServerSession } from "next-auth";
import { AuthOptions } from "@/app/api/auth/[...nextauth]/authOptions";
import { redirect, notFound } from "next/navigation";
import { eq, inArray, and, desc, sql } from "drizzle-orm";
import { db } from "@/app/db/db";
import { hubspotDealData } from "@/app/db/schema/crm/hubspot_deal_table";
import { portfolioOrganisation } from "@/app/db/schema/portfolio_organisation";
import { organisation } from "@/app/db/schema/organisation";
import { portfolioCapabilities, portfolioUsers } from "@/app/db/schema/portfolio";
import { dealMeasureApprovals } from "@/app/db/schema/approvals";
import { propertyRemovalRequests } from "@/app/db/schema/removal_requests";
import { user as userTable } from "@/app/db/schema/users";
import type { DocStatus, PortfolioCapabilityType } from "../types";
import { deriveEffectiveRemovalState } from "../removalState";
import { classifyDeals } from "../transforms";
import { fetchDocsByDealId, computeDocStatusMap } from "../docStatus";
import { coordinatorUser, designerUser, mapDbRowToHubspotDeal } from "../dealQuery";
import type { DealRow } from "../dealQuery";
import DealPage from "./DealPage";
import Link from "next/link";

export default async function DealDetailPage(props: {
  params: Promise<{ slug: string; dealId: string }>;
}) {
  const { slug: portfolioId, dealId } = await props.params;
  const session = await getServerSession(AuthOptions);

  if (!session?.user) {
    redirect("/");
  }

  const links = await db
    .select({ hubspotCompanyId: organisation.hubspotCompanyId })
    .from(portfolioOrganisation)
    .innerJoin(
      organisation,
      eq(portfolioOrganisation.organisationId, organisation.id),
    )
    .where(eq(portfolioOrganisation.portfolioId, BigInt(portfolioId)));

  const companyIds = links
    .map((l) => l.hubspotCompanyId)
    .filter((id): id is string => !!id);

  if (companyIds.length === 0) {
    redirect(`/portfolio/${portfolioId}/your-projects/live`);
  }

  const rawDeals = await db
    .select({
      deal: hubspotDealData,
      coordinator: sql<string | null>`CASE WHEN ${hubspotDealData.coordinator} IS NULL THEN NULL ELSE COALESCE(${coordinatorUser.firstName} || ' ' || ${coordinatorUser.lastName}, 'Domna Coordinator') END`,
      designer: sql<string | null>`CASE WHEN ${hubspotDealData.designer} IS NULL THEN NULL ELSE COALESCE(${designerUser.firstName} || ' ' || ${designerUser.lastName}, 'Domna Designer') END`,
    })
    .from(hubspotDealData)
    .leftJoin(
      coordinatorUser,
      eq(hubspotDealData.coordinator, coordinatorUser.hubspotOwnerId),
    )
    .leftJoin(
      designerUser,
      eq(hubspotDealData.designer, designerUser.hubspotOwnerId),
    )
    .where(
      and(
        inArray(hubspotDealData.companyId, companyIds),
        eq(hubspotDealData.dealId, dealId),
      ),
    )
    .limit(1);

  if (!rawDeals.length) {
    notFound();
  }

  const hubspotDeal = mapDbRowToHubspotDeal(rawDeals[0]);
  const [deal] = classifyDeals([hubspotDeal]);

  const userEmail = session.user.email;
  let userCapability: PortfolioCapabilityType = [];
  let userRole = "read";

  if (userEmail) {
    const userRow = await db
      .select({ id: userTable.id })
      .from(userTable)
      .where(eq(userTable.email, userEmail))
      .limit(1);

    if (userRow[0]) {
      const [capRows, roleRow] = await Promise.all([
        db
          .select({ capability: portfolioCapabilities.capability })
          .from(portfolioCapabilities)
          .where(
            and(
              eq(portfolioCapabilities.portfolioId, BigInt(portfolioId)),
              eq(portfolioCapabilities.userId, userRow[0].id),
            ),
          ),
        db
          .select({ role: portfolioUsers.role })
          .from(portfolioUsers)
          .where(
            and(
              eq(portfolioUsers.portfolioId, BigInt(portfolioId)),
              eq(portfolioUsers.userId, userRow[0].id),
            ),
          )
          .limit(1),
      ]);

      userCapability = capRows
        .map((r) => r.capability)
        .filter(
          (c): c is "approver" | "contractor" =>
            c === "approver" || c === "contractor",
        );
      userRole = roleRow[0]?.role ?? "read";
    }
  }

  const approvedMeasures: string[] = [];
  const approvalRows = await db
    .select({ measureName: dealMeasureApprovals.measureName })
    .from(dealMeasureApprovals)
    .where(
      and(
        eq(dealMeasureApprovals.hubspotDealId, dealId),
        eq(dealMeasureApprovals.isApproved, true),
      ),
    );
  approvedMeasures.push(...approvalRows.map((r) => r.measureName));

  const removalRows = await db
    .select({
      type: propertyRemovalRequests.type,
      status: propertyRemovalRequests.status,
    })
    .from(propertyRemovalRequests)
    .where(
      and(
        eq(propertyRemovalRequests.portfolioId, BigInt(portfolioId)),
        eq(propertyRemovalRequests.hubspotDealId, dealId),
      ),
    )
    .orderBy(desc(propertyRemovalRequests.requestedAt))
    .limit(1);

  const removalState = removalRows[0]
    ? deriveEffectiveRemovalState(removalRows[0])
    : "none";

  const docsByDealId = await fetchDocsByDealId([hubspotDeal], [dealId]);
  const docStatusMap = computeDocStatusMap([hubspotDeal], docsByDealId, { [dealId]: approvedMeasures });
  const docStatus: DocStatus = docStatusMap[dealId] ?? {
    presentSurveyTypes: [],
    hasSurveyDocs: false,
    isSurveyComplete: false,
    hasInstallDocs: false,
    installStatus: "none",
    measureProgress: [],
  };

  return (
    <div className="max-w-screen-2xl mx-auto px-6 pb-10 space-y-4">
      <div className="mb-6">
        <nav className="flex items-center gap-1.5 text-sm text-gray-500 mb-3">
          <Link
            href={`/portfolio/${portfolioId}/your-projects/live`}
            className="hover:text-brandblue transition-colors"
          >
            Live Projects
          </Link>
          <span className="text-gray-300">/</span>
          <span className="text-gray-800 font-medium truncate max-w-xs">
            {deal.dealname ?? dealId}
          </span>
        </nav>
        <div className="h-px bg-gray-200" />
      </div>
      <DealPage
        deal={deal}
        portfolioId={portfolioId}
        userRole={userRole}
        userCapability={userCapability}
        approvedMeasures={approvedMeasures}
        docStatus={docStatus}
        removalState={removalState}
        userEmail={userEmail ?? ""}
      />
    </div>
  );
}
