import React, { useState } from "react";
import { Ban, Pencil, RotateCcw } from "lucide-react";
import { Card, CardContent, CardHeader, CardTitle } from "./card";
import { Button } from "./button";
import { Spinner } from "./spinner";
import { Badge } from "./badge";
import { Chip } from "./chip";
import { CategoryEditDialog, type CategoryItem } from "./category-edit-dialog";
import {
  Tooltip,
  TooltipContent,
  TooltipProvider,
  TooltipTrigger,
} from "./tooltip";
import { cn } from "@/lib/utils";
import { formatCurrency } from "@/lib/format-currency";
import { formatDateShort } from "@/lib/format-date";

// ─── Types ───────────────────────────────────────────────────────────────────

export interface DashboardTransaction {
  id: string;
  /** ISO date string — "2024-04-15" or full ISO */
  date: string;
  description: string;
  /** Optional merchant / location sub-label */
  merchant?: string;
  /** Signed dollar amount — positive = credit, negative = debit */
  amount: number;
  /** Display label for the category chip */
  category?: string;
  /** Category ID used for filter matching */
  categoryId?: string;
  /** User-overridden category name — displayed instead of `category` when set */
  editedCategoryName?: string;
  /** When true, the row is excluded from calculations (dimmed, amount struck through) */
  isExcluded?: boolean;
}

export type { CategoryItem };

export interface DashboardTransactionsTableProps {
  transactions?: DashboardTransaction[];
  title?: string;
  /** Show a "Load More" button when more pages are available */
  hasNextPage?: boolean;
  isLoadingMore?: boolean;
  onLoadMore?: () => void;
  isLoading?: boolean;
  className?: string;
  /**
   * Active category filter ID. Rows whose categoryId does not match are dimmed.
   * Pass null / undefined to show all rows at full opacity.
   */
  selectedCategoryId?: string | null;
  /**
   * Category tree for the built-in CategoryEditDialog.
   * When provided, clicking a category chip opens the dialog inline.
   */
  categories?: CategoryItem[];
  /**
   * Called after the user saves a category change via the built-in dialog.
   */
  onCategoryChange?: (
    transactionId: string,
    categoryId: string,
    applyToFuture: boolean,
  ) => void;
  /**
   * When provided, each row shows an exclude/restore icon button that toggles
   * whether the transaction is counted in calculations.
   */
  onToggleExclude?: (transaction: DashboardTransaction) => void;
  /**
   * Show or hide the card header (title + tab row).
   * Set to `false` when the surrounding layout already provides context.
   * Defaults to `true`.
   */
  showHeader?: boolean;
  /**
   * Show or hide the "Account Transaction" underlined tab below the title.
   * Set to `false` when the surrounding layout already provides tab context.
   * Defaults to `true`.
   */
  showTab?: boolean;
  /**
   * Colour scheme for the editable category chip hover state.
   * - `"primary"` (default) — green hover
   * - `"secondary"` — dark navy hover; use when the surrounding context uses the secondary palette (e.g. expense view)
   */
  colorScheme?: "primary" | "secondary";
}

// ─── Category chip ────────────────────────────────────────────────────────────

function CategoryChip({
  label,
  canEdit,
  colorScheme = "primary",
  onClick,
}: {
  label: string;
  canEdit: boolean;
  colorScheme?: "primary" | "secondary";
  onClick?: () => void;
}) {
  if (canEdit) {
    return (
      <Badge
        asChild
        variant="secondary"
        className={cn(
          "cursor-pointer transition-colors",
          colorScheme === "secondary"
            ? "hover:bg-brand-secondary/10 hover:text-[var(--brand-secondary)]"
            : "hover:border-primary/40 hover:bg-primary/10 hover:text-primary",
        )}
      >
        <button type="button" onClick={onClick}>
          {label}
          <Pencil className="size-2.5 shrink-0 opacity-60" />
        </button>
      </Badge>
    );
  }

  return <Chip variant="secondary">{label}</Chip>;
}

// ─── Transaction row ──────────────────────────────────────────────────────────

function TransactionRow({
  tx,
  isDimmed,
  canEdit,
  colorScheme = "primary",
  onChipClick,
  onToggleExclude,
}: {
  tx: DashboardTransaction;
  isDimmed: boolean;
  canEdit: boolean;
  colorScheme?: "primary" | "secondary";
  onChipClick?: () => void;
  onToggleExclude?: (transaction: DashboardTransaction) => void;
}) {
  const isCredit = tx.amount >= 0;
  const categoryLabel = tx.editedCategoryName ?? tx.category;
  const excludeLabel = tx.isExcluded
    ? "Restore transaction"
    : "Exclude from calculations";

  return (
    <div
      className={cn(
        "flex items-start justify-between gap-4 border-b border-border py-3 last:border-0 transition-opacity",
        isDimmed && "opacity-30",
        tx.isExcluded && "opacity-50",
      )}
    >
      <div className="min-w-0 flex-1">
        <p className="text-sm text-muted-foreground">
          {formatDateShort(tx.date)}
        </p>
        <p className="mt-0.5 truncate text-base font-medium text-foreground">
          {tx.description}
        </p>
        {tx.merchant && (
          <p className="mt-0.5 truncate text-sm text-muted-foreground">
            {tx.merchant}
          </p>
        )}
        {categoryLabel && (
          <div className="mt-1">
            <CategoryChip
              label={categoryLabel}
              canEdit={canEdit}
              colorScheme={colorScheme}
              onClick={onChipClick}
            />
          </div>
        )}
      </div>

      <div className="flex shrink-0 items-center gap-1.5">
        <span
          className={cn(
            "text-base font-semibold",
            isCredit ? "text-success" : "text-foreground",
            tx.isExcluded && "line-through",
          )}
        >
          {isCredit ? "+" : ""}
          {formatCurrency(tx.amount, { showSign: false })}
        </span>
        {onToggleExclude && (
          <Tooltip>
            <TooltipTrigger
              render={
                <button
                  type="button"
                  aria-label={excludeLabel}
                  onClick={() => onToggleExclude(tx)}
                  className="flex size-7 shrink-0 items-center justify-center text-muted-foreground transition-colors hover:text-foreground"
                >
                  {tx.isExcluded ? (
                    <RotateCcw className="size-4" />
                  ) : (
                    <Ban className="size-4" />
                  )}
                </button>
              }
            />
            <TooltipContent>
              {tx.isExcluded
                ? "Restore transaction"
                : "Exclude from calculations"}
            </TooltipContent>
          </Tooltip>
        )}
      </div>
    </div>
  );
}

// ─── Component ────────────────────────────────────────────────────────────────

export function DashboardTransactionsTable({
  transactions = [],
  title = "Transaction History",
  hasNextPage = false,
  isLoadingMore = false,
  onLoadMore,
  isLoading = false,
  className,
  selectedCategoryId,
  categories,
  onCategoryChange,
  onToggleExclude,
  showHeader = true,
  showTab = true,
  colorScheme = "primary",
}: DashboardTransactionsTableProps) {
  const isFiltering = selectedCategoryId != null;
  const canEdit = !!categories?.length;

  const [editingTx, setEditingTx] = useState<DashboardTransaction | null>(null);

  const handleSave = (categoryId: string, applyToFuture: boolean) => {
    if (editingTx) {
      onCategoryChange?.(editingTx.id, categoryId, applyToFuture);
    }
    setEditingTx(null);
  };

  return (
    <>
      <Card className={cn("flex flex-col", className)}>
        {showHeader && (
          <CardHeader className="pb-0">
            <CardTitle className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
              {title}
            </CardTitle>
            {showTab && (
              <div className="mt-2 flex border-b border-border">
                <span className="border-b-2 border-foreground pb-1.5 text-xs font-semibold text-foreground">
                  Account Transaction
                </span>
              </div>
            )}
          </CardHeader>
        )}

        <CardContent className="flex flex-1 flex-col px-4 pb-0 pt-0">
          {isLoading ? (
            <div className="flex flex-1 items-center justify-center py-8">
              <Spinner size="default" />
            </div>
          ) : transactions.length === 0 ? (
            <p className="py-8 text-center text-sm text-muted-foreground">
              No transactions found
            </p>
          ) : (
            <TooltipProvider>
              <div className="flex flex-col">
                {transactions.map((tx) => (
                  <TransactionRow
                    key={tx.id}
                    tx={tx}
                    isDimmed={
                      isFiltering && tx.categoryId !== selectedCategoryId
                    }
                    canEdit={canEdit}
                    colorScheme={colorScheme}
                    onChipClick={() => setEditingTx(tx)}
                    onToggleExclude={onToggleExclude}
                  />
                ))}
              </div>
            </TooltipProvider>
          )}

          {hasNextPage && onLoadMore && (
            <div className="py-4 text-center">
              <Button
                variant="outline"
                size="sm"
                onClick={onLoadMore}
                disabled={isLoadingMore}
              >
                {isLoadingMore ? "Loading…" : "Load More"}
              </Button>
            </div>
          )}
        </CardContent>
      </Card>

      {canEdit && (
        <CategoryEditDialog
          open={editingTx !== null}
          onOpenChange={(open) => !open && setEditingTx(null)}
          transactionDescription={editingTx?.description}
          currentCategoryId={editingTx?.categoryId}
          categories={categories!}
          onSave={handleSave}
        />
      )}
    </>
  );
}
