"use client";

import { useState } from "react";

import {
  type ColumnDef,
  type Table as TableType,
  getCoreRowModel,
  useReactTable,
} from "@tanstack/react-table";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { CheckCircle2, GitBranch, Loader2, RefreshCw } from "lucide-react";
import { DataTable } from "@/components/tables/DataTable";
import { cn } from "@/lib/utils";

import type {
  ForgejoRepository,
  ForgejoRepositoryValidationResponse,
} from "@/lib/api-forgejo";

type RepositorySyncResult = {
  created: number;
  updated: number;
  open: number;
  closed: number;
  total: number;
};

interface RepositoriesTableProps {
  repositories: ForgejoRepository[];
  isLoading: boolean;
  onEdit?: (repository: ForgejoRepository) => void;
  onDelete?: (repository: ForgejoRepository) => void;
  onSync?: (repository: ForgejoRepository) => Promise<RepositorySyncResult>;
  onValidate?: (
    repository: ForgejoRepository,
  ) => Promise<ForgejoRepositoryValidationResponse>;
}

export function ForgejoRepositoriesTable({
  repositories,
  isLoading,
  onEdit,
  onDelete,
  onSync,
  onValidate,
}: RepositoriesTableProps) {
  // onEdit available for future use
  const _ = onEdit;
  const table = useReactTable({
    data: repositories,
    columns: columns(onSync, onValidate),
    getCoreRowModel: getCoreRowModel(),
  });

  return (
    <DataTable
      table={table}
      isLoading={isLoading}
      emptyState={{
        icon: <GitBranch className="h-12 w-12" />,
        title: "No Git Project repositories yet",
        description:
          "Add repositories so Pipeline can sync issues into Git Projects.",
        actionHref: "/git-projects/repositories/new",
        actionLabel: "Add repository",
      }}
      rowActions={{
        getEditHref: (row) => `/git-projects/repositories/${row.id}/edit`,
        onDelete: onDelete ?? undefined,
      }}
      tableClassName="min-w-[860px] w-full text-left text-sm"
    />
  );
}

const columns = (
  onSync?: (repository: ForgejoRepository) => Promise<RepositorySyncResult>,
  onValidate?: (
    repository: ForgejoRepository,
  ) => Promise<ForgejoRepositoryValidationResponse>,
): ColumnDef<ForgejoRepository>[] => [
  {
    accessorKey: "displayName",
    header: ({ column }) => {
      return (
        <Button
          variant="ghost"
          onClick={() => column.toggleSorting(false)}
          className="h-auto px-0 py-0 hover:bg-transparent hover:text-[color:var(--accent)]"
        >
          Repository
          {column.getIsSorted() === "asc" && "↑"}
          {column.getIsSorted() === "desc" && "↓"}
        </Button>
      );
    },
    cell: ({ row }) => {
      const repo = row.original;
      return (
        <div className="min-w-0">
          <span className="block truncate font-medium text-strong">
            {repo.display_name || `${repo.owner}/${repo.repo}`}
          </span>
          <span className="block truncate font-mono text-xs text-muted">
            {repo.owner}/{repo.repo} • {repo.connection?.name}
          </span>
        </div>
      );
    },
  },
  {
    accessorKey: "connection",
    header: "Connection",
    cell: ({ row }) => {
      const connection = row.original.connection;
      return (
        <div className="min-w-0">
          <span className="block truncate text-sm text-strong">
            {connection?.name}
          </span>
          <span className="block truncate text-xs text-muted">
            {connection?.base_url}
          </span>
        </div>
      );
    },
  },
  {
    accessorKey: "status",
    header: "Status",
    cell: ({ row }) => {
      const isActive = row.original.active;
      return (
        <Badge variant={isActive ? "default" : "outline"}>
          {isActive ? "Active" : "Inactive"}
        </Badge>
      );
    },
  },
  {
    accessorKey: "lastSync",
    header: "Last Sync",
    cell: ({ row }) => {
      const lastSyncAt = row.original.last_sync_at;
      const lastSyncError = row.original.last_sync_error;

      if (!lastSyncAt) {
        return <span className="text-sm text-muted">Never</span>;
      }

      const date = new Date(lastSyncAt);

      return (
        <div className="flex flex-col">
          <span className="text-sm text-strong">
            {date.toLocaleDateString()}
          </span>
          <span className="text-xs text-muted">
            {date.toLocaleTimeString()}
          </span>
          {lastSyncError && (
            <span className="max-w-[220px] truncate text-xs text-[color:var(--danger)]">
              Error: {lastSyncError.substring(0, 50)}...
            </span>
          )}
        </div>
      );
    },
  },
  {
    id: "actions",
    cell: ({ row }) => (
      <ActionsCell
        repository={row.original}
        onSync={onSync}
        onValidate={onValidate}
      />
    ),
  },
];

function ActionsCell({
  repository,
  onSync,
  onValidate,
}: {
  repository: ForgejoRepository;
  onSync?: (repository: ForgejoRepository) => Promise<RepositorySyncResult>;
  onValidate?: (
    repository: ForgejoRepository,
  ) => Promise<ForgejoRepositoryValidationResponse>;
}) {
  const [isSyncLoading, setIsSyncLoading] = useState(false);
  const [isValidateLoading, setIsValidateLoading] = useState(false);
  const [syncResult, setSyncResult] = useState<{
    created: number;
    updated: number;
    open: number;
    closed: number;
    total: number;
  } | null>(null);
  const [validateResult, setValidateResult] = useState<{
    ok: boolean;
    repo_exists?: boolean;
    error_message?: string;
  } | null>(null);

  const handleSync = async () => {
    if (!onSync) return;
    setIsSyncLoading(true);
    try {
      const result = await onSync(repository);
      setSyncResult(result);
    } finally {
      setIsSyncLoading(false);
    }
  };

  const handleValidate = async () => {
    if (!onValidate) return;
    setIsValidateLoading(true);
    try {
      const result = await onValidate(repository);
      setValidateResult({
        ok: result.status.ok,
        repo_exists: result.repo_exists ?? undefined,
        error_message: result.status.error_message ?? undefined,
      });
    } finally {
      setIsValidateLoading(false);
    }
  };

  return (
    <div className="flex items-center gap-2">
      {onSync && (
        <Button
          variant="ghost"
          onClick={handleSync}
          disabled={isSyncLoading}
          className="h-8 w-8 p-0"
          title="Sync issues"
        >
          {isSyncLoading ? (
            <Loader2 className="h-4 w-4 animate-spin" />
          ) : syncResult ? (
            <CheckCircle2 className="h-4 w-4 text-[color:var(--success)]" />
          ) : (
            <RefreshCw className="h-4 w-4" />
          )}
        </Button>
      )}
      {onValidate && (
        <Button
          variant="ghost"
          onClick={handleValidate}
          disabled={isValidateLoading}
          className="h-8 w-8 p-0"
          title="Validate repository"
        >
          {isValidateLoading ? (
            <Loader2 className="h-4 w-4 animate-spin" />
          ) : validateResult?.ok ? (
            <CheckCircle2 className="h-4 w-4 text-[color:var(--success)]" />
          ) : (
            <CheckCircle2 className="h-4 w-4" />
          )}
        </Button>
      )}
    </div>
  );
}

// Filter component
export function RepositoriesTableFilter({
  value,
  onChange,
}: {
  value: string;
  onChange: (value: string) => void;
}) {
  return (
    <input
      type="text"
      placeholder="Filter repositories…"
      value={value ?? ""}
      onChange={(e) => onChange(e.target.value)}
      className="h-9 w-[150px] rounded-xl border border-[color:var(--border)] bg-[color:var(--surface)] px-3 py-1 text-sm text-strong focus:border-[color:var(--accent)] focus:outline-none focus:ring-2 focus:ring-[color:var(--accent)] lg:w-[250px]"
    />
  );
}

// Column toggle component
export function RepositoriesTableToggle({
  table,
}: {
  table: TableType<ForgejoRepository>;
}) {
  return (
    <div className="flex items-center gap-2">
      <div className="flex items-center gap-2">
        <span className="text-xs text-muted">Show:</span>
        <Button
          variant="ghost"
          size="sm"
          onClick={() => table.toggleAllColumnsVisible()}
          className="h-8 px-2 py-1 text-xs"
        >
          All
        </Button>
        <Button
          variant="ghost"
          size="sm"
          onClick={() => table.toggleAllColumnsVisible(false)}
          className="h-8 px-2 py-1 text-xs"
        >
          None
        </Button>
      </div>
      <div className="flex gap-1">
        {table
          .getAllColumns()
          .filter((column) => column.getCanHide())
          .map((column) => {
            return (
              <Button
                key={column.id}
                variant="ghost"
                size="sm"
                onClick={() => column.toggleVisibility(!column.getIsVisible())}
                className={cn(
                  "h-8 px-2 py-1 text-xs",
                  column.getIsVisible()
                    ? "bg-[color:var(--surface-strong)] text-strong"
                    : "text-muted",
                )}
              >
                {column.id}
              </Button>
            );
          })}
      </div>
    </div>
  );
}
