import { db } from "@/app/db/db";
import { property } from "@/app/db/schema/property";
import { inArray, eq, and } from "drizzle-orm";
import { surveyDB } from "@/app/db/surveyDB/connection";
import { uploadedFiles } from "@/app/db/surveyDB/schema/surveyDB";
import { getEnergyAssessmentFromS3 } from "@/app/portfolio/[slug]/building-passport/[propertyId]/utils";
import DecentHomesDashboard from "./DecentHomesDashboard";

async function getPropertiesWithUprn(
  portfolioId: string,
  limit = 1000,
  offset = 0
): Promise<any[]> {
  const data = await db.query.property.findMany({
    limit,
    offset,
    columns: {
      id: true,
      uprn: true,
      address: true,
      postcode: true,
    },
    where: eq(property.portfolioId, BigInt(portfolioId)),
  });
  return data;
}

async function getDocumentsForUprns(
  uprns: (string | number)[]
): Promise<Map<string, Map<string, typeof uploadedFiles.$inferSelect>>> {
  const rows = await surveyDB.query.uploadedFiles.findMany({
    where: and(
      inArray(uploadedFiles.uprn, uprns.map(String)),
      inArray(uploadedFiles.docType, [
        "DECENT_HOMES_SUMMARY",
        "DECENT_HOMES_PROPERTY_META",
      ])
    ),
    orderBy: (uploadedFiles, { desc }) => [
      desc(uploadedFiles.s3JsonUploadTimestamp),
    ],
  });

  // Map<UPRN, Map<docType, row>>
  const latestByUprn = new Map<string, Map<string, (typeof rows)[number]>>();

  for (const row of rows) {
    if (!latestByUprn.has(row.uprn)) {
      latestByUprn.set(row.uprn, new Map());
    }
    const docMap = latestByUprn.get(row.uprn)!;

    // if this docType isn’t already set, use it (rows are ordered newest first)
    if (!docMap.has(row.docType)) {
      docMap.set(row.docType, row);
    }
  }

  return latestByUprn;
}

export default async function DecentHomesPage({
  params,
  searchParams,
}: {
  params: Promise<{ slug: string }>;
  searchParams: Promise<{
    [key: string]: string | string[] | undefined | number;
  }>;
}) {
  const { slug: portfolioId } = await params;
  const properties = await getPropertiesWithUprn(portfolioId, 1000, 0);
  const uprns = properties.map((p) => String(p.uprn));
  const documentsMap = await getDocumentsForUprns(uprns);

  const summaryResults = await Promise.all(
    properties.map(async (property) => {
      const propertyDocs = documentsMap.get(String(property.uprn));
      const propertyDecentHomes = propertyDocs?.get("DECENT_HOMES_SUMMARY");
      const propertyDecentHomesMeta = propertyDocs?.get(
        "DECENT_HOMES_PROPERTY_META"
      );

      if (
        !propertyDecentHomes?.s3JsonUri ||
        !propertyDecentHomesMeta?.s3JsonUri
      ) {
        return {
          id: property.id,
          uprn: property.uprn,
          address: property.address,
          postcode: property.postcode,
          decent_homes: "no_data",
          criterion_a: "no_data",
          criterion_b: "no_data",
          criterion_c: "no_data",
          criterion_d: "no_data",
          replacements: [],
        };
      }

      const decentHomes = await getEnergyAssessmentFromS3(
        propertyDecentHomes.s3JsonUri
      );
      const decentHomesMeta = await getEnergyAssessmentFromS3(
        propertyDecentHomesMeta.s3JsonUri
      );

      return {
        id: property.id,
        uprn: property.uprn,
        address: property.address,
        postcode: property.postcode,
        decent_homes: decentHomes.decent_homes,
        criterion_a: decentHomes.criterion_a,
        criterion_b: decentHomes.criterion_b,
        criterion_c: decentHomes.criterion_c,
        criterion_d: decentHomes.criterion_d,
        replacements: decentHomesMeta.map((m: any) => ({
          sub_variable: m.sub_variable,
          expiry_date: m.expiry_date ?? null,
        })),
      };
    })
  );

  return (
    <div className="container mx-auto px-4">
      <DecentHomesDashboard data={summaryResults} portfolioId={portfolioId} />
    </div>
  );
}
