/**
 * TransactionHistory Component
 * Full wallet transaction history with filtering and pagination
 */

import React, { useState, useEffect, useMemo } from 'react';
import {
  ArrowDownLeft,
  ArrowUpRight,
  Filter,
  ChevronLeft,
  ChevronRight,
  Download,
  Loader2,
  Clock,
  CheckCircle,
  XCircle,
  AlertCircle,
  RefreshCw,
} from 'lucide-react';
import { getWalletTransactions } from '../../services/payment.service';
import type {
  WalletTransaction,
  TransactionType as BaseTransactionType,
  TransactionStatus,
} from '../../types/payment.types';

// Extended filter type for the component (includes 'all')
export type TransactionFilterType = BaseTransactionType | 'all';

// Re-export for backward compatibility
export type { TransactionStatus };
export type TransactionType = BaseTransactionType;

// Transaction interface for component display
export interface Transaction {
  id: string;
  type: TransactionFilterType;
  amount: number;
  currency: string;
  status: TransactionStatus;
  description: string;
  createdAt: string;
  completedAt?: string;
  reference?: string;
  metadata?: Record<string, unknown>;
}

interface TransactionHistoryProps {
  walletId?: string;
  filterType?: TransactionFilterType;
  itemsPerPage?: number;
  showPagination?: boolean;
  showFilter?: boolean;
  showExport?: boolean;
  onTransactionClick?: (transaction: Transaction) => void;
  compact?: boolean;
}

const TransactionHistory: React.FC<TransactionHistoryProps> = ({
  walletId,
  filterType: initialFilter = 'all',
  itemsPerPage = 10,
  showPagination = true,
  showFilter = true,
  showExport = true,
  onTransactionClick,
  compact = false,
}) => {
  const [transactions, setTransactions] = useState<Transaction[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [currentPage, setCurrentPage] = useState(1);
  const [totalPages, setTotalPages] = useState(1);
  const [filterType, setFilterType] = useState<TransactionFilterType>(initialFilter);

  const fetchTransactions = async () => {
    setLoading(true);
    setError(null);

    try {
      const offset = (currentPage - 1) * itemsPerPage;
      const typeFilter = filterType !== 'all' ? filterType : undefined;
      const result = await getWalletTransactions(itemsPerPage, offset, typeFilter);

      // Map WalletTransaction to local Transaction type
      const mappedTransactions: Transaction[] = result.transactions.map((tx) => ({
        id: tx.id,
        type: tx.type,
        amount: tx.amount,
        currency: tx.currency,
        status: tx.status,
        description: tx.description,
        createdAt: tx.createdAt,
        completedAt: tx.processedAt,
        reference: tx.referenceId,
        metadata: tx.metadata,
      }));

      setTransactions(mappedTransactions);
      setTotalPages(Math.ceil(result.total / itemsPerPage));
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load transactions');
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchTransactions();
  }, [walletId, filterType, currentPage, itemsPerPage]);

  const handleExport = () => {
    // Generate CSV
    const headers = ['Date', 'Type', 'Description', 'Amount', 'Status', 'Reference'];
    const rows = transactions.map((tx) => [
      new Date(tx.createdAt).toLocaleString(),
      tx.type,
      tx.description,
      `${tx.amount >= 0 ? '+' : ''}${tx.amount.toFixed(2)} ${tx.currency}`,
      tx.status,
      tx.reference || '',
    ]);

    const csv = [headers, ...rows].map((row) => row.join(',')).join('\n');
    const blob = new Blob([csv], { type: 'text/csv' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `transactions-${new Date().toISOString().split('T')[0]}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  };

  const formatDate = (dateString: string) => {
    const date = new Date(dateString);
    const now = new Date();
    const diff = now.getTime() - date.getTime();

    if (diff < 60000) return 'Just now';
    if (diff < 3600000) return `${Math.floor(diff / 60000)}m ago`;
    if (diff < 86400000) return `${Math.floor(diff / 3600000)}h ago`;
    if (diff < 604800000) return date.toLocaleDateString('en-US', { weekday: 'short' });
    return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
  };

  const getTypeIcon = (type: TransactionFilterType) => {
    switch (type) {
      case 'deposit':
        return <ArrowDownLeft className="w-4 h-4 text-green-400" />;
      case 'withdrawal':
        return <ArrowUpRight className="w-4 h-4 text-red-400" />;
      case 'fee':
      case 'purchase':
        return <ArrowUpRight className="w-4 h-4 text-orange-400" />;
      case 'refund':
        return <ArrowDownLeft className="w-4 h-4 text-blue-400" />;
      case 'transfer_in':
        return <ArrowDownLeft className="w-4 h-4 text-purple-400" />;
      case 'transfer_out':
        return <ArrowUpRight className="w-4 h-4 text-purple-400" />;
      case 'earning':
      case 'distribution':
      case 'bonus':
      case 'reward':
        return <ArrowDownLeft className="w-4 h-4 text-green-400" />;
      default:
        return <Clock className="w-4 h-4 text-gray-400" />;
    }
  };

  const getStatusIcon = (status: TransactionStatus) => {
    switch (status) {
      case 'completed':
        return <CheckCircle className="w-4 h-4 text-green-400" />;
      case 'pending':
      case 'processing':
        return <Clock className="w-4 h-4 text-yellow-400" />;
      case 'failed':
        return <XCircle className="w-4 h-4 text-red-400" />;
      case 'cancelled':
      case 'reversed':
        return <AlertCircle className="w-4 h-4 text-gray-400" />;
      default:
        return <Clock className="w-4 h-4 text-gray-400" />;
    }
  };

  const getStatusColor = (status: TransactionStatus) => {
    switch (status) {
      case 'completed':
        return 'text-green-400 bg-green-500/20';
      case 'pending':
      case 'processing':
        return 'text-yellow-400 bg-yellow-500/20';
      case 'failed':
        return 'text-red-400 bg-red-500/20';
      case 'cancelled':
      case 'reversed':
        return 'text-gray-400 bg-gray-500/20';
      default:
        return 'text-gray-400 bg-gray-500/20';
    }
  };

  if (loading && transactions.length === 0) {
    return (
      <div className="flex items-center justify-center py-8">
        <Loader2 className="w-6 h-6 text-blue-400 animate-spin" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="text-center py-8">
        <AlertCircle className="w-10 h-10 text-red-400 mx-auto mb-3" />
        <p className="text-gray-400 mb-4">{error}</p>
        <button
          onClick={fetchTransactions}
          className="px-4 py-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg text-sm"
        >
          Retry
        </button>
      </div>
    );
  }

  return (
    <div className="space-y-4">
      {/* Header with Filter & Export */}
      {(showFilter || showExport) && (
        <div className="flex items-center justify-between">
          {showFilter && (
            <div className="flex items-center gap-2">
              <Filter className="w-4 h-4 text-gray-500" />
              <select
                value={filterType}
                onChange={(e) => {
                  setFilterType(e.target.value as TransactionFilterType);
                  setCurrentPage(1);
                }}
                className="px-3 py-1.5 bg-gray-800 border border-gray-700 rounded-lg text-sm text-white focus:outline-none focus:border-blue-500"
              >
                <option value="all">All Transactions</option>
                <option value="deposit">Deposits</option>
                <option value="withdrawal">Withdrawals</option>
                <option value="payment">Payments</option>
                <option value="refund">Refunds</option>
              </select>
            </div>
          )}

          <div className="flex items-center gap-2">
            <button
              onClick={fetchTransactions}
              disabled={loading}
              className="p-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-colors disabled:opacity-50"
              title="Refresh"
            >
              <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
            </button>
            {showExport && transactions.length > 0 && (
              <button
                onClick={handleExport}
                className="flex items-center gap-2 px-3 py-1.5 text-sm text-gray-300 hover:text-white hover:bg-gray-700 rounded-lg transition-colors"
              >
                <Download className="w-4 h-4" />
                Export
              </button>
            )}
          </div>
        </div>
      )}

      {/* Transaction List */}
      {transactions.length === 0 ? (
        <div className="text-center py-8">
          <Clock className="w-10 h-10 text-gray-600 mx-auto mb-3" />
          <p className="text-gray-400">No transactions found</p>
        </div>
      ) : (
        <div className="space-y-2">
          {transactions.map((tx) => (
            <div
              key={tx.id}
              onClick={() => onTransactionClick?.(tx)}
              className={`flex items-center justify-between p-3 bg-gray-800/50 rounded-lg border border-gray-700 ${
                onTransactionClick ? 'cursor-pointer hover:bg-gray-800' : ''
              } transition-colors`}
            >
              <div className="flex items-center gap-3">
                <div className="p-2 bg-gray-900/50 rounded-lg">
                  {getTypeIcon(tx.type)}
                </div>
                <div>
                  <p className="text-white font-medium">
                    {tx.description || tx.type.charAt(0).toUpperCase() + tx.type.slice(1)}
                  </p>
                  <div className="flex items-center gap-2 text-sm text-gray-500">
                    <span>{formatDate(tx.createdAt)}</span>
                    {tx.reference && !compact && (
                      <>
                        <span>•</span>
                        <span className="font-mono text-xs">{tx.reference}</span>
                      </>
                    )}
                  </div>
                </div>
              </div>

              <div className="text-right">
                <p className={`font-medium font-mono ${
                  tx.amount >= 0 ? 'text-green-400' : 'text-red-400'
                }`}>
                  {tx.amount >= 0 ? '+' : ''}{tx.amount.toFixed(2)} {tx.currency}
                </p>
                <div className={`inline-flex items-center gap-1 px-2 py-0.5 rounded text-xs ${getStatusColor(tx.status)}`}>
                  {getStatusIcon(tx.status)}
                  <span className="capitalize">{tx.status}</span>
                </div>
              </div>
            </div>
          ))}
        </div>
      )}

      {/* Pagination */}
      {showPagination && totalPages > 1 && (
        <div className="flex items-center justify-between pt-2">
          <p className="text-sm text-gray-500">
            Page {currentPage} of {totalPages}
          </p>
          <div className="flex items-center gap-2">
            <button
              onClick={() => setCurrentPage((p) => Math.max(1, p - 1))}
              disabled={currentPage === 1}
              className="p-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <ChevronLeft className="w-4 h-4" />
            </button>
            <button
              onClick={() => setCurrentPage((p) => Math.min(totalPages, p + 1))}
              disabled={currentPage === totalPages}
              className="p-2 text-gray-400 hover:text-white hover:bg-gray-700 rounded-lg transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <ChevronRight className="w-4 h-4" />
            </button>
          </div>
        </div>
      )}
    </div>
  );
};

export default TransactionHistory;
