"use client";

import * as React from "react";
import { FileText, Loader2, X } from "lucide-react";
import { useParams } from "next/navigation";
import { Controller, type Control, type FieldPath, type FieldValues } from "react-hook-form";

import { transactionFieldLabels } from "@/components/form/common/field-labels";
import { formFieldClass } from "@/components/form/common/form-layout";
import { Button } from "@/components/ui/button";
import { Field, FieldError, FieldLabel } from "@/components/ui/field";
import { customerCsrfHeader } from "@/lib/customer-csrf.client";
import { cn } from "@/lib/utils";

const MAX_FILE_BYTES = 1 * 1024 * 1024;
const ACCEPTED_TYPES = ".pdf,application/pdf";

type ReferenceLinkFieldProps<T extends FieldValues> = {
  control: Control<T>;
  name: FieldPath<T>;
  label?: string;
  className?: string;
};

function fileNameFromPath(path: string): string {
  const trimmed = path.trim();
  if (!trimmed) return "";
  const parts = trimmed.split("/");
  return parts[parts.length - 1] ?? trimmed;
}

export function ReferenceLinkField<T extends FieldValues>({
  control,
  name,
  label = transactionFieldLabels.r_link,
  className,
}: ReferenceLinkFieldProps<T>) {
  const params = useParams<{ tenant?: string }>();
  const tenant = params.tenant ?? "";
  const inputRef = React.useRef<HTMLInputElement>(null);
  const [uploading, setUploading] = React.useState(false);
  const [uploadError, setUploadError] = React.useState<string | null>(null);

  return (
    <Controller
      control={control}
      name={name}
      render={({ field, fieldState }) => {
        const storedPath = String(field.value ?? "").trim();
        const displayName = fileNameFromPath(storedPath);

        async function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
          const file = event.target.files?.[0];
          event.target.value = "";
          if (!file) return;

          if (file.type !== "application/pdf" && !file.name.toLowerCase().endsWith(".pdf")) {
            setUploadError("Only PDF files are allowed.");
            return;
          }

          if (file.size > MAX_FILE_BYTES) {
            setUploadError("Maximum file size is 1 MB.");
            return;
          }

          setUploadError(null);
          setUploading(true);

          try {
            const body = new FormData();
            body.append("file", file);

            const response = await fetch(`/customer/${tenant}/reference-link/upload`, {
              method: "POST",
              credentials: "same-origin",
              headers: customerCsrfHeader(tenant),
              body,
            });

            const data = (await response.json().catch(() => null)) as {
              status?: string;
              filepath?: string;
              message?: string;
            } | null;

            if (!response.ok || data?.status !== "success" || !data.filepath) {
              setUploadError(
                typeof data?.message === "string" ? data.message : "Could not upload file.",
              );
              return;
            }

            field.onChange(data.filepath);
          } catch {
            setUploadError("Could not upload file.");
          } finally {
            setUploading(false);
          }
        }

        return (
          <Field className={cn(formFieldClass, className)} data-invalid={!!fieldState.error || !!uploadError}>
            <FieldLabel htmlFor={`${String(name)}-browse`}>{label}</FieldLabel>

            {storedPath ? (
              <div className="flex items-center gap-2 rounded-md border border-input bg-muted/20 px-3 py-2 text-sm">
                <FileText className="text-muted-foreground size-4 shrink-0" />
                <span className="min-w-0 flex-1 truncate" title={displayName}>
                  {displayName}
                </span>
                <Button
                  type="button"
                  variant="ghost"
                  size="icon-sm"
                  aria-label="Remove file"
                  onClick={() => field.onChange("")}
                >
                  <X className="size-4" />
                </Button>
              </div>
            ) : null}

            <div className="flex items-center gap-2">
              <input
                ref={inputRef}
                id={`${String(name)}-browse`}
                type="file"
                accept={ACCEPTED_TYPES}
                className="sr-only"
                onChange={handleFileChange}
                disabled={uploading}
              />
              <Button
                type="button"
                variant="outline"
                disabled={uploading}
                onClick={() => inputRef.current?.click()}
              >
                {uploading ? <Loader2 className="size-4 animate-spin" /> : null}
                Browse
              </Button>
              <span className="text-muted-foreground text-xs">PDF, max 1 MB</span>
            </div>

            {uploadError ? <p className="text-destructive text-sm">{uploadError}</p> : null}
            {fieldState.error ? <FieldError errors={[fieldState.error]} /> : null}
          </Field>
        );
      }}
    />
  );
}
