"use client";
import { useRouter } from "next/navigation";
import React from "react";
import { TableCell, TableRow } from "@/app/shadcn_components/ui/table";
import { BrandButton } from "@/app/components/Buttons";
import { UploadModal } from "./UploadModal";
import {
  documentTypeTitles,
  type ReportType,
} from "@/app/db/surveyDB/schema/documents";
import type { getUploadedFiles } from "@/app/db/surveyDB/schema/surveyDB";
import type { FilesFromSurveyor } from "@/app/db/schema/files_from_surveyor";
import { useMutation } from "@tanstack/react-query";

type Props = {
  reportType: ReportType | null;
  uprn: string;
  files: getUploadedFiles | FilesFromSurveyor[];
};

type AnyFile = Record<string, unknown>;

const DATE_KEYS = [
  "uploadedAt",
  "s3FileUploadTimestamp",
  "createdAt",
  "updatedAt",
  "timestamp",
] as const;

const URL_KEYS = ["s3FileUri", "s3JsonUrl", "url", "href", "link"] as const;

function pickFirst<T = unknown>(
  obj: AnyFile,
  keys: readonly string[]
): T | undefined {
  for (const k of keys) {
    if (k in obj && obj[k] != null) return obj[k] as T;
  }
  return undefined;
}

function asDate(val: unknown): Date | undefined {
  if (!val) return undefined;
  if (val instanceof Date) return val;
  const d = new Date(String(val));
  return isNaN(d.getTime()) ? undefined : d;
}

type NormalizedFile = {
  url?: string;
  uploadedAt?: Date;
  original: AnyFile;
};

const NAME_KEYS = ["name", "filename", "fileName", "title"] as const;

function normalizeFile(f: AnyFile): NormalizedFile & { name?: string } {
  const url = pickFirst<string>(f, URL_KEYS);
  const dateRaw = pickFirst<unknown>(f, DATE_KEYS);
  const uploadedAt = asDate(dateRaw);

  let name = pickFirst<string>(f, NAME_KEYS);
  if (!name && url) {
    // Extract last path segment from URL
    const parts = url.split("/");
    name = decodeURIComponent(parts[parts.length - 1]);
  }

  return { url, uploadedAt, name, original: f };
}

function getLatestNormalized(files: AnyFile[]): NormalizedFile | null {
  if (!Array.isArray(files) || files.length === 0) return null;
  const normalized = files.map(normalizeFile);

  // Prefer items that have a valid uploadedAt. If none have a date, fall back to first.
  const withDate = normalized.filter((n) => n.uploadedAt);
  if (withDate.length === 0) return normalized[0];

  return withDate.reduce((acc, cur) =>
    cur.uploadedAt!.getTime() > acc.uploadedAt!.getTime() ? cur : acc
  );
}

function formatWhen(d: Date | string) {
  const date = new Date(d);
  const yyyy = date.getUTCFullYear();
  const mm = String(date.getUTCMonth() + 1).padStart(2, "0");
  const dd = String(date.getUTCDate()).padStart(2, "0");
  const hh = String(date.getUTCHours()).padStart(2, "0");
  const min = String(date.getUTCMinutes()).padStart(2, "0");
  return `${dd} ${["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][date.getUTCMonth()]} ${yyyy}, ${hh}:${min} UTC`;
}

export function usePresignedUrl() {
  return useMutation({
    mutationFn: async (key: string) => {
      const res = await fetch("/api/sign-s3-url", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ key }),
      });

      if (!res.ok) {
        throw new Error("Failed to get presigned URL");
      }

      const data = await res.json();
      return data.url as string;
    },
  });
}

export const DocumentSection: React.FC<Props> = ({
  reportType,
  uprn,
  files,
}) => {
  const [showUploadModal, setShowUploadModal] = React.useState(false);
  const router = useRouter();

  const latest = React.useMemo(
    () => getLatestNormalized(files as unknown as AnyFile[]),
    [files]
  );

  const title =
    reportType && documentTypeTitles[reportType] !== "Other"
      ? documentTypeTitles[reportType]
      : latest?.url
        ? decodeURIComponent(latest.url.split("/").pop() || "")
        : "Other";

  const count = files.length;

  const latestUpload = latest?.uploadedAt ? formatWhen(latest.uploadedAt) : "";

  const { mutateAsync: getSignedUrl, isPending } = usePresignedUrl();

  const handleViewFile = async (fileUrl: string) => {
    try {
      // Extract S3 key from the full URL
      const bucketDomain = "retrofit-data-dev.s3.eu-west-2.amazonaws.com/";
      const key = fileUrl.split(bucketDomain)[1];
      if (!key) throw new Error("Invalid S3 file URL");

      const signedUrl = await getSignedUrl(key);
      window.open(signedUrl, "_blank", "noopener,noreferrer");
    } catch (err) {
      console.error("Failed to open presigned URL:", err);
      alert("Could not open file.");
    }
  };

  return (
    <>
      <TableRow className="bg-gray-50">
        <TableCell
          className="px-4 py-4 text-sm text-gray-900 max-w-[250px] truncate"
          title={title}
        >
          {title}
        </TableCell>

        <TableCell className="px-6 py-4 text-sm text-gray-500">
          {latest ? (
            <div className="flex flex-col gap-1">
              <div className="flex items-center gap-3">
                {latest.url ? (
                  <button
                    type="button"
                    onClick={() => handleViewFile(latest.url!)}
                    disabled={isPending}
                    className="underline underline-offset-2 hover:no-underline disabled:opacity-50"
                  >
                    {isPending ? "Loading..." : "View latest file"}
                  </button>
                ) : (
                  <span className="text-gray-400">Latest file has no URL</span>
                )}
                {latestUpload && (
                  <div className="text-xs text-gray-400">
                    uploaded {latestUpload}
                  </div>
                )}
              </div>
              <span className="text-xs text-gray-500">
                {count} file{count !== 1 && "s"} on record
              </span>
            </div>
          ) : (
            <span className="text-gray-400">No files uploaded yet</span>
          )}
        </TableCell>

        {reportType ? (
          <TableCell className="px-6 py-4 text-sm text-right w-1/6">
            <BrandButton
              label="Upload"
              onClick={() => setShowUploadModal(true)}
              backgroundColor="brandblue"
            />
            <UploadModal
              open={showUploadModal}
              onClose={() => {
                setShowUploadModal(false);
                router.refresh();
              }}
              documentType={reportType}
              uprn={uprn}
            />
          </TableCell>
        ) : (
          <TableCell className="px-6 py-4 text-sm text-right w-1/6"></TableCell>
        )}
      </TableRow>
    </>
  );
};
