import * as React from "react";
import { FileTextIcon, XIcon } from "lucide-react";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { UploadCard } from "@/components/ui/upload-card";

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

export interface CsvImportModalProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  /** Controlled: display name of the currently selected file. */
  fileName?: string;
  /** Controlled: size of the currently selected file in bytes. */
  fileSize?: number;
  /** Called when the user picks a file via the upload zone. */
  onFileSelect?: (file: File) => void;
  /** Called when the user removes the currently selected file. */
  onFileClear?: () => void;
  /** Called when the user clicks Next (a file must already be selected). */
  onNext: () => void;
  /** Called when the user clicks the CSV template download link. */
  onDownloadTemplate?: () => void;
  /** Override the upload zone description (e.g. for a stricter file-size cap). */
  uploadDescription?: string;
  isLoading?: boolean;
  className?: string;
}

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function formatBytes(bytes: number): string {
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
}

// ---------------------------------------------------------------------------
// Component
// ---------------------------------------------------------------------------

export function CsvImportModal({
  open,
  onOpenChange,
  fileName,
  fileSize,
  onFileSelect,
  onFileClear,
  onNext,
  onDownloadTemplate,
  uploadDescription,
  isLoading = false,
  className,
}: CsvImportModalProps) {
  const hasFile = !!fileName;

  return (
    <Dialog open={open} onOpenChange={isLoading ? undefined : onOpenChange}>
      <DialogContent size="md" className={className}>
        <DialogHeader>
          <DialogTitle>Import Clients</DialogTitle>
        </DialogHeader>

        <p className="text-sm text-muted-foreground">
          Upload a CSV file to bulk-import clients into WealthX.{" "}
          {onDownloadTemplate ? (
            <button
              type="button"
              onClick={onDownloadTemplate}
              className="text-primary underline-offset-2 hover:underline"
            >
              Download the CSV template
            </button>
          ) : (
            "Download the CSV template"
          )}{" "}
          to get started.
        </p>

        {hasFile ? (
          <SelectedFile
            name={fileName!}
            size={fileSize}
            onClear={onFileClear}
          />
        ) : (
          <UploadCard
            size="lg"
            label="Drag & drop or click to upload"
            description={uploadDescription ?? "Supports .csv files only. Max 10 MB."}
            accept=".csv"
            onFileChange={(file) => file && onFileSelect?.(file)}
          />
        )}

        <DialogFooter>
          <Button
            variant="outline"
            onClick={() => onOpenChange(false)}
            disabled={isLoading}
          >
            Cancel
          </Button>
          <Button disabled={!hasFile || isLoading} onClick={onNext}>
            Next
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

// ---------------------------------------------------------------------------
// Sub-component
// ---------------------------------------------------------------------------

function SelectedFile({
  name,
  size,
  onClear,
}: {
  name: string;
  size?: number;
  onClear?: () => void;
}) {
  return (
    <div className="flex items-center gap-3 border border-border bg-muted/30 px-4 py-3">
      <FileTextIcon className="size-4 shrink-0 text-muted-foreground" />
      <div className="min-w-0 flex-1">
        <p className="truncate text-sm font-medium text-foreground">{name}</p>
        {size !== undefined && (
          <p className="text-xs text-muted-foreground">{formatBytes(size)}</p>
        )}
      </div>
      {onClear && (
        <button
          type="button"
          onClick={onClear}
          aria-label="Remove file"
          className="shrink-0 text-muted-foreground hover:text-foreground"
        >
          <XIcon className="size-4" />
        </button>
      )}
    </div>
  );
}
