import React, { useState, useMemo, useTransition } from 'react';

// Custom hooks
const useDebounce = <T,>(value: T, delay: number): T => {
  const [debouncedValue, setDebouncedValue] = useState(value);

  React.useEffect(() => {
    const handler = setTimeout(() => setDebouncedValue(value), delay);
    return () => clearTimeout(handler);
  }, [value, delay]);

  return debouncedValue;
};

const useToast = () => {
  const [toast, setToast] = useState<string | null>(null);

  const showToast = (message: string) => {
    setToast(message);
    setTimeout(() => setToast(null), 3000);
  };

  return { toast, showToast };
};

// Mock data
const mockInvoices = [
  { id: '1001', customer: 'Acme Corp', amount: 5250.00, status: 'paid', dueDate: '2024-01-15', invoiceDate: '2024-01-01' },
  { id: '1002', customer: 'Tech Solutions Inc', amount: 12500.00, status: 'unpaid', dueDate: '2024-02-01', invoiceDate: '2024-01-15' },
  { id: '1003', customer: 'Global Enterprises', amount: 8750.50, status: 'overdue', dueDate: '2024-01-20', invoiceDate: '2024-01-05' },
  { id: '1004', customer: 'Startup LLC', amount: 3200.00, status: 'paid', dueDate: '2024-01-25', invoiceDate: '2024-01-10' },
  { id: '1005', customer: 'Enterprise Co', amount: 15000.00, status: 'unpaid', dueDate: '2024-02-10', invoiceDate: '2024-01-20' },
  { id: '1006', customer: 'Small Biz Inc', amount: 1850.75, status: 'overdue', dueDate: '2024-01-18', invoiceDate: '2024-01-03' },
];

type Invoice = typeof mockInvoices[0];

const App: React.FC = () => {
  const [searchQuery, setSearchQuery] = useState('');
  const [filterStatus, setFilterStatus] = useState<string>('all');
  const [isPending, startTransition] = useTransition();
  const { toast, showToast } = useToast();

  const debouncedSearch = useDebounce(searchQuery, 300);

  const filteredInvoices = useMemo(() => {
    return mockInvoices.filter((invoice) => {
      const matchesSearch =
        invoice.customer.toLowerCase().includes(debouncedSearch.toLowerCase()) ||
        invoice.id.includes(debouncedSearch);
      const matchesFilter = filterStatus === 'all' || invoice.status === filterStatus;
      return matchesSearch && matchesFilter;
    });
  }, [debouncedSearch, filterStatus]);

  const stats = useMemo(() => {
    const total = mockInvoices.reduce((sum, inv) => sum + inv.amount, 0);
    const paid = mockInvoices.filter(i => i.status === 'paid').reduce((sum, inv) => sum + inv.amount, 0);
    const unpaid = mockInvoices.filter(i => i.status === 'unpaid').reduce((sum, inv) => sum + inv.amount, 0);
    const overdue = mockInvoices.filter(i => i.status === 'overdue').reduce((sum, inv) => sum + inv.amount, 0);
    return { total, paid, unpaid, overdue };
  }, []);

  const handleFilterChange = (status: string) => {
    startTransition(() => {
      setFilterStatus(status);
      showToast(`Filter: ${status === 'all' ? 'All Invoices' : status.charAt(0).toUpperCase() + status.slice(1)}`);
    });
  };

  return (
    <div className="app-container">
      <header className="app-header">
        <h1>Invoice Dashboard</h1>
        <p>Manage and track all your invoices</p>
      </header>

      <div className="stats-grid">
        <div className="stat-card">
          <div className="stat-label">Total Invoiced</div>
          <div className="stat-value">${stats.total.toLocaleString('en-US', { minimumFractionDigits: 2 })}</div>
        </div>
        <div className="stat-card stat-success">
          <div className="stat-label">Paid</div>
          <div className="stat-value">${stats.paid.toLocaleString('en-US', { minimumFractionDigits: 2 })}</div>
        </div>
        <div className="stat-card stat-warning">
          <div className="stat-label">Unpaid</div>
          <div className="stat-value">${stats.unpaid.toLocaleString('en-US', { minimumFractionDigits: 2 })}</div>
        </div>
        <div className="stat-card stat-danger">
          <div className="stat-label">Overdue</div>
          <div className="stat-value">${stats.overdue.toLocaleString('en-US', { minimumFractionDigits: 2 })}</div>
        </div>
      </div>

      <div className="controls">
        <input
          type="text"
          className="search-input"
          placeholder="Search by customer or invoice #..."
          value={searchQuery}
          onChange={(e) => setSearchQuery(e.target.value)}
        />
        <div className="filter-buttons">
          {['all', 'paid', 'unpaid', 'overdue'].map((status) => (
            <button
              key={status}
              className={`filter-btn ${filterStatus === status ? 'active' : ''}`}
              onClick={() => handleFilterChange(status)}
            >
              {status.charAt(0).toUpperCase() + status.slice(1)}
            </button>
          ))}
        </div>
      </div>

      {filteredInvoices.length === 0 ? (
        <div className="empty-state">
          <div className="empty-icon">📄</div>
          <h3>No invoices found</h3>
          <p>Try adjusting your search or filters</p>
        </div>
      ) : (
        <div className={`data-grid ${isPending ? 'loading' : ''}`}>
          <table>
            <thead>
              <tr>
                <th>Invoice #</th>
                <th>Customer</th>
                <th>Invoice Date</th>
                <th>Due Date</th>
                <th>Amount</th>
                <th>Status</th>
              </tr>
            </thead>
            <tbody>
              {filteredInvoices.map((invoice) => (
                <tr key={invoice.id}>
                  <td className="invoice-id">#{invoice.id}</td>
                  <td className="customer-name">{invoice.customer}</td>
                  <td>{invoice.invoiceDate}</td>
                  <td>{invoice.dueDate}</td>
                  <td className="amount">${invoice.amount.toLocaleString('en-US', { minimumFractionDigits: 2 })}</td>
                  <td>
                    <span className={`status-badge status-${invoice.status}`}>
                      {invoice.status}
                    </span>
                  </td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}

      {toast && <div className="toast">{toast}</div>}
    </div>
  );
};

export default App;
