# React Hooks for Rclone Transfer Service

This directory contains React hooks that wrap the unified rclone transfer service with React state management, loading states, progress tracking, and error handling.

## Available Hooks

### `useRcloneTransfer`

A React hook for managing single file and folder transfers.

#### Features
- Loading state management.
- Progress tracking with percentage.
- Error handling.
- Transfer cancellation.
- Automatic cleanup on unmount.

#### Usage

```typescript
import { useRcloneTransfer } from "~/lib/rclone";

function FileTransferComponent() {
  const {
    isLoading,
    metadata,
    error,
    progressPercentage,
    status,
    startFileTransfer,
    startFolderTransfer,
    cancelCurrentTransfer,
    reset,
  } = useRcloneTransfer({
    onStart: (metadata) => {
      console.log("Transfer started:", metadata.operationId);
    },
    onProgress: (metadata) => {
      console.log(`Progress: ${metadata.progress?.percentage}%`);
    },
    onComplete: (metadata) => {
      console.log("Transfer completed successfully");
    },
    onError: (metadata, error) => {
      console.error("Transfer failed:", error);
    },
    onCancel: (metadata) => {
      console.log("Transfer cancelled");
    },
  });

  const handleFileTransfer = async () => {
    const operationId = await startFileTransfer({
      sourceService: "google",
      sourceAccountId: "default",
      sourceFileId: "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
      destService: "dropbox",
      destAccountId: "default",
      destFolderId: "root",
      fileName: "my-document.pdf",
    });

    if (operationId) {
      console.log("Transfer started with ID:", operationId);
    }
  };

  const handleFolderTransfer = async () => {
    const operationId = await startFolderTransfer({
      sourceService: "google",
      sourceAccountId: "default",
      sourceFolderId: "1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms",
      destService: "dropbox",
      destAccountId: "default",
      destFolderId: "root",
      folderName: "My Documents",
      preserveStructure: true,
    });

    if (operationId) {
      console.log("Folder transfer started with ID:", operationId);
    }
  };

  return (
    <div>
      <button onClick={handleFileTransfer} disabled={isLoading}>
        Transfer File
      </button>
      <button onClick={handleFolderTransfer} disabled={isLoading}>
        Transfer Folder
      </button>

      {isLoading && (
        <div>
          <p>Transfer in progress... {progressPercentage}%</p>
          <button onClick={cancelCurrentTransfer}>Cancel</button>
        </div>
      )}

      {error && (
        <div style={{ color: "red" }}>
          Error: {error}
        </div>
      )}

      {status === "completed" && (
        <div style={{ color: "green" }}>
          Transfer completed successfully!
        </div>
      )}
    </div>
  );
}
```

### `useRcloneBatchTransfer`

A React hook for managing batch file transfers with multiple concurrent operations.

#### Features
- Batch transfer management.
- Individual operation tracking.
- Overall progress calculation.
- Selective cancellation.
- Failed operation handling.

#### Usage

```typescript
import { useRcloneBatchTransfer } from "~/lib/rclone";

function BatchTransferComponent() {
  const {
    isLoading,
    batchId,
    operations,
    totalOperations,
    completedOperations,
    failedOperations,
    overallProgress,
    startBatchTransfer,
    cancelAllTransfers,
    cancelTransfer,
    getOperation,
    reset,
  } = useRcloneBatchTransfer({
    onBatchStart: (batchId, operationIds) => {
      console.log(`Batch ${batchId} started with ${operationIds.length} operations`);
    },
    onBatchProgress: (operations) => {
      const completed = operations.filter(op => op.status === "completed").length;
      console.log(`Batch progress: ${completed}/${operations.length} completed`);
    },
    onBatchComplete: (operations) => {
      console.log("Batch transfer completed");
    },
    onBatchError: (error, operations) => {
      console.error("Batch transfer error:", error);
    },
    onOperationProgress: (operationId, metadata) => {
      console.log(`Operation ${operationId}: ${metadata.progress?.percentage}%`);
    },
    onOperationComplete: (operationId, metadata) => {
      console.log(`Operation ${operationId} completed`);
    },
    onOperationError: (operationId, metadata, error) => {
      console.error(`Operation ${operationId} failed:`, error);
    },
  });

  const handleBatchTransfer = async () => {
    const batchId = await startBatchTransfer({
      operations: [
        {
          sourceService: "google",
          sourceAccountId: "default",
          sourceFileId: "file1-id",
          destService: "dropbox",
          destAccountId: "default",
          destFolderId: "root",
          fileName: "file1.pdf",
        },
        {
          sourceService: "google",
          sourceAccountId: "default",
          sourceFileId: "file2-id",
          destService: "dropbox",
          destAccountId: "default",
          destFolderId: "root",
          fileName: "file2.pdf",
        },
        // ... more operations
      ],
    });

    if (batchId) {
      console.log("Batch transfer started with ID:", batchId);
    }
  };

  return (
    <div>
      <button onClick={handleBatchTransfer} disabled={isLoading}>
        Start Batch Transfer
      </button>

      {isLoading && (
        <div>
          <h3>Batch Transfer Progress</h3>
          <p>Overall Progress: {overallProgress.toFixed(1)}%</p>
          <p>
            Completed: {completedOperations} / {totalOperations}
            {failedOperations > 0 && ` (${failedOperations} failed)`}
          </p>

          <div>
            {operations.map((operation) => (
              <div key={operation.operationId}>
                <span>{operation.operationId}: </span>
                <span>{operation.status} - {operation.progressPercentage}%</span>
                {operation.error && (
                  <span style={{ color: "red" }}> - {operation.error}</span>
                )}
                {operation.isLoading && (
                  <button onClick={() => cancelTransfer(operation.operationId)}>
                    Cancel
                  </button>
                )}
              </div>
            ))}
          </div>

          <button onClick={cancelAllTransfers}>Cancel All</button>
        </div>
      )}
    </div>
  );
}
```

## Hook Options

### Common Options

Both hooks accept similar callback options:

- `onStart?: (metadata: TransferMetadata) => void` - Called when transfer starts.
- `onProgress?: (metadata: TransferMetadata) => void` - Called on progress updates.
- `onComplete?: (metadata: TransferMetadata) => void` - Called when transfer completes.
- `onError?: (metadata: TransferMetadata, error: string) => void` - Called when transfer fails.
- `onCancel?: (metadata: TransferMetadata) => void` - Called when transfer is cancelled.
- `pollIntervalMs?: number` - Polling interval in milliseconds (default: 2000).

### Batch-Specific Options

`useRcloneBatchTransfer` also accepts:

- `onBatchStart?: (batchId: string, operationIds: string[]) => void`.
- `onBatchProgress?: (operations: BatchOperationStatus[]) => void`.
- `onBatchComplete?: (operations: BatchOperationStatus[]) => void`.
- `onBatchError?: (error: string, operations: BatchOperationStatus[]) => void`.
- `onOperationProgress?: (operationId: string, metadata: TransferMetadata) => void`.
- `onOperationComplete?: (operationId: string, metadata: TransferMetadata) => void`.
- `onOperationError?: (operationId: string, metadata: TransferMetadata, error: string) => void`.
- `onOperationCancel?: (operationId: string, metadata: TransferMetadata) => void`.

## Error Handling

Both hooks provide comprehensive error handling:

1. **Network Errors**: Automatically handled and exposed via the `error` state
2. **Transfer Failures**: Reported through the `onError` callback and `error` state
3. **Cancellation**: Clean cancellation with proper cleanup
4. **Timeout Handling**: Built into the underlying transfer service

## Best Practices

1. **Always handle errors**: Use the `error` state and `onError` callback
2. **Provide user feedback**: Use `isLoading` and `progressPercentage` for UI updates
3. **Allow cancellation**: Provide cancel buttons for long-running transfers
4. **Clean up**: Use the `reset()` function when appropriate
5. **Monitor progress**: Use progress callbacks for detailed monitoring

## Integration with Components

These hooks are designed to be used in React components that need to perform file transfers. They handle all the complexity of the transfer service while providing a clean, React-friendly interface.

The hooks automatically:
- Start and stop polling based on transfer state.
- Clean up resources on component unmount.
- Provide derived state (like progress percentage).
- Handle multiple concurrent operations (batch hook).
