import { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import {
  ArrowRight,
  TrendingUp,
  TrendingDown,
  RefreshCw,
  CreditCard,
  Pencil,
  Check,
  X,
} from 'lucide-react';

import api, { type Account, type Transaction } from '../api';

function formatAmount(amount: number, currency: string) {
  const abs = Math.abs(amount);
  if (currency === 'BTC') return abs.toFixed(8);
  if (currency === 'XMR') return abs.toFixed(4);
  if (currency === 'USD') {
    return `$${abs.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
  }
  return `₡${abs.toLocaleString('es-CR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
}

function formatDate(dateStr: string) {
  return new Date(dateStr).toLocaleDateString('en-US', { month: 'short', day: 'numeric' });
}

// --- Reusable card for an account balance ---
function AccountCard({
  account,
  editingId,
  editValue,
  setEditValue,
  startEditing,
  saveBalance,
  cancelEditing,
}: {
  account: Account;
  editingId: number | null;
  editValue: string;
  setEditValue: (v: string) => void;
  startEditing: (a: Account) => void;
  saveBalance: (id: number) => void;
  cancelEditing: () => void;
}) {
  const badgeLabel = account.account_type === 'CRYPTO' ? account.label : (account.bank === 'DAVIVIENDA' ? 'DAV' : account.bank);
  const isEditing = editingId === account.id;

  return (
    <div className="group animate-fade-in bg-surface dark:bg-slate-900 border border-border dark:border-slate-700 rounded-xl p-5 shadow-sm dark:shadow-none hover:bg-surface-hover dark:hover:bg-slate-800/60 transition-colors h-[104px] flex flex-col justify-between">
      <div className="flex items-center justify-end">
        <span className="text-sm font-bold font-mono text-text-secondary dark:text-slate-300 bg-surface-secondary dark:bg-slate-800 px-2.5 py-0.5 rounded">
          {badgeLabel}
        </span>
      </div>
      {isEditing ? (
        <div className="flex items-center gap-2">
          <input
            type="number"
            step="0.01"
            value={editValue}
            onChange={(e) => setEditValue(e.target.value)}
            onKeyDown={(e) => {
              if (e.key === 'Enter') saveBalance(account.id);
              if (e.key === 'Escape') cancelEditing();
            }}
            autoFocus
            className="w-full text-2xl font-bold font-mono tracking-tight bg-input-bg border border-[#606C38]/40 rounded-lg px-2 py-1 focus:outline-none focus:border-[#606C38] transition-colors"
          />
          <button onClick={() => saveBalance(account.id)} className="p-1 text-[#606C38] dark:text-[#7a8a4a]">
            <Check className="w-4 h-4" />
          </button>
          <button onClick={cancelEditing} className="p-1 text-text-muted hover:text-text-secondary">
            <X className="w-4 h-4" />
          </button>
        </div>
      ) : (
        <div className="flex items-center gap-2 group/balance cursor-pointer" onClick={() => startEditing(account)}>
          <p className="text-2xl font-bold font-mono tracking-tight">
            {formatAmount(account.balance, account.currency)}
          </p>
          <Pencil className="w-3.5 h-3.5 text-text-faint opacity-0 group-hover/balance:opacity-100 hover:text-[#606C38] dark:hover:text-[#7a8a4a] transition-all" />
        </div>
      )}
    </div>
  );
}

// --- Total card ---
function TotalCard({ total, currency }: { total: number; currency: string }) {
  return (
    <div className="border rounded-xl p-5 shadow-sm dark:shadow-none h-[104px] flex flex-col justify-between bg-[#fdf3e3] dark:bg-[#BC6C25]/10 border-[#e8c08a] dark:border-[#BC6C25]/20 text-[#8a5218] dark:text-[#DDA15E]">
      <span className="text-xs font-bold uppercase tracking-wider opacity-80">Total</span>
      <p className="text-2xl font-bold font-mono tracking-tight">{formatAmount(total, currency)}</p>
    </div>
  );
}

export default function Dashboard() {
  const [accounts, setAccounts] = useState<Account[]>([]);
  const [recent, setRecent] = useState<Transaction[]>([]);
  const [loading, setLoading] = useState(true);
  const [editingId, setEditingId] = useState<number | null>(null);
  const [editValue, setEditValue] = useState('');
  const [exchangeRate, setExchangeRate] = useState<{ buy_rate: number; sell_rate: number } | null>(null);

  const fetchData = async () => {
    setLoading(true);
    try {
      const [accRes, txRes] = await Promise.all([
        api.get('/accounts/'),
        api.get('/transactions/recent?limit=5'),
      ]);
      setAccounts(accRes.data);
      setRecent(txRes.data);
    } catch (e) {
      console.error(e);
    } finally {
      setLoading(false);
    }
    api.get('/exchange-rate/').then((r) => setExchangeRate(r.data)).catch(() => {});
  };

  useEffect(() => { fetchData(); }, []);

  const startEditing = (account: Account) => {
    setEditingId(account.id);
    setEditValue(String(account.balance));
  };
  const cancelEditing = () => { setEditingId(null); setEditValue(''); };
  const saveBalance = async (accountId: number) => {
    const parsed = parseFloat(editValue);
    if (isNaN(parsed)) return cancelEditing();
    try {
      await api.patch(`/accounts/${accountId}`, { balance: parsed });
      setEditingId(null);
      setEditValue('');
      fetchData();
    } catch (e) { console.error(e); }
  };

  const cardProps = { editingId, editValue, setEditValue, startEditing, saveBalance, cancelEditing };

  // Group accounts by type
  const bankAccounts = accounts.filter((a) => a.account_type === 'BANK');
  const pensionAccounts = accounts.filter((a) => a.account_type === 'PENSION');
  const savingsAccounts = accounts.filter((a) => a.account_type === 'SAVINGS');
  const liabilityAccounts = accounts.filter((a) => a.account_type === 'LIABILITY');
  const cryptoAccounts = accounts.filter((a) => a.account_type === 'CRYPTO');

  const bankOrder = ['BAC', 'BCR', 'DAVIVIENDA'];

  // Bank totals for exchange rate combined total
  const bankCRC = bankAccounts.filter((a) => a.currency === 'CRC').reduce((s, a) => s + a.balance, 0);
  const bankUSD = bankAccounts.filter((a) => a.currency === 'USD').reduce((s, a) => s + a.balance, 0);

  return (
    <div className="space-y-6">
      {/* Header */}
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Dashboard</h1>
          <p className="text-sm text-text-muted mt-1">Financial overview</p>
        </div>
        <button
          onClick={fetchData}
          className="p-2 rounded-lg text-text-muted hover:text-text-primary hover:bg-surface-hover transition-colors"
        >
          <RefreshCw className={`w-4 h-4 ${loading ? 'animate-spin' : ''}`} />
        </button>
      </div>

      {/* Bank accounts — grouped by currency */}
      {(['CRC', 'USD'] as const).map((currency) => {
        const accts = bankAccounts
          .filter((a) => a.currency === currency)
          .sort((a, b) => bankOrder.indexOf(a.bank) - bankOrder.indexOf(b.bank));
        if (accts.length === 0) return null;
        const total = accts.reduce((s, a) => s + a.balance, 0);

        return (
          <div key={currency} className="space-y-2">
            <h2 className="text-xs font-semibold text-text-muted uppercase tracking-wider">{currency} Accounts</h2>
            <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
              {accts.map((a) => <AccountCard key={a.id} account={a} {...cardProps} />)}
              <TotalCard total={total} currency={currency} />
            </div>
          </div>
        );
      })}

      {/* Pension accounts */}
      {pensionAccounts.length > 0 && (
        <div className="space-y-2">
          <h2 className="text-xs font-semibold text-text-muted uppercase tracking-wider">Pension</h2>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            {pensionAccounts.map((a) => <AccountCard key={a.id} account={a} {...cardProps} />)}
            <TotalCard
              total={pensionAccounts.reduce((s, a) => s + a.balance, 0)}
              currency="CRC"
            />
          </div>
        </div>
      )}

      {/* Savings accounts */}
      {savingsAccounts.length > 0 && (
        <div className="space-y-2">
          <h2 className="text-xs font-semibold text-text-muted uppercase tracking-wider">Savings</h2>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            {savingsAccounts.map((a) => <AccountCard key={a.id} account={a} {...cardProps} />)}
            <TotalCard
              total={savingsAccounts.reduce((s, a) => s + a.balance, 0)}
              currency="CRC"
            />
          </div>
        </div>
      )}

      {/* Liabilities */}
      {liabilityAccounts.length > 0 && (
        <div className="space-y-2">
          <h2 className="text-xs font-semibold text-text-muted uppercase tracking-wider">Liabilities</h2>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            {liabilityAccounts.map((account) => {
              const bankShort = account.bank === 'DAVIVIENDA' ? 'DAV' : account.bank;
              return (
                <div
                  key={account.id}
                  className="animate-fade-in bg-red-50 dark:bg-red-500/5 border border-red-200 dark:border-red-500/20 rounded-xl p-5 shadow-sm dark:shadow-none hover:bg-red-100/50 dark:hover:bg-red-500/10 transition-colors"
                >
                  <div className="flex items-center justify-between mb-2">
                    <span className="text-xs font-bold text-red-700 dark:text-red-400/80 uppercase tracking-wider">
                      Balance
                    </span>
                    <span className="text-sm font-bold font-mono text-red-600 dark:text-red-400 bg-red-100 dark:bg-red-500/10 px-2.5 py-0.5 rounded">
                      {bankShort}
                    </span>
                  </div>
                  <p
                    className="text-2xl font-bold font-mono tracking-tight text-red-700 dark:text-red-400 cursor-pointer group/balance"
                    onClick={() => startEditing(account)}
                  >
                    {editingId === account.id ? (
                      <span className="flex items-center gap-2">
                        <input
                          type="number"
                          step="0.01"
                          value={editValue}
                          onChange={(e) => setEditValue(e.target.value)}
                          onKeyDown={(e) => {
                            if (e.key === 'Enter') saveBalance(account.id);
                            if (e.key === 'Escape') cancelEditing();
                          }}
                          autoFocus
                          className="w-full text-2xl font-bold font-mono tracking-tight bg-input-bg border border-red-500/40 rounded-lg px-2 py-1 focus:outline-none focus:border-red-500 transition-colors text-text-primary"
                          onClick={(e) => e.stopPropagation()}
                        />
                        <button onClick={(e) => { e.stopPropagation(); saveBalance(account.id); }} className="p-1 text-red-500">
                          <Check className="w-4 h-4" />
                        </button>
                        <button onClick={(e) => { e.stopPropagation(); cancelEditing(); }} className="p-1 text-text-muted">
                          <X className="w-4 h-4" />
                        </button>
                      </span>
                    ) : (
                      formatAmount(account.balance, account.currency)
                    )}
                  </p>
                  {account.next_payment != null && (
                    <p className="text-sm font-mono text-red-600/70 dark:text-red-400/60 mt-2">
                      Next payment: {formatAmount(account.next_payment, account.currency)}
                    </p>
                  )}
                </div>
              );
            })}
          </div>
        </div>
      )}

      {/* Crypto */}
      {cryptoAccounts.length > 0 && (
        <div className="space-y-2">
          <h2 className="text-xs font-semibold text-text-muted uppercase tracking-wider">Crypto</h2>
          <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
            {cryptoAccounts.map((a) => <AccountCard key={a.id} account={a} {...cardProps} />)}
          </div>
        </div>
      )}

      {/* Exchange rate + combined total */}
      {exchangeRate && (
        <div className="flex flex-col sm:flex-row gap-4">
          <div className="flex-1 bg-surface-card border border-border rounded-xl p-4">
            <span className="text-xs font-medium text-text-muted uppercase tracking-wider">USD/CRC Exchange Rate</span>
            <div className="flex items-baseline gap-3 mt-1">
              <span className="text-lg font-bold font-mono">Buy: ₡{exchangeRate.buy_rate.toFixed(2)}</span>
              <span className="text-lg font-bold font-mono text-text-secondary">Sell: ₡{exchangeRate.sell_rate.toFixed(2)}</span>
            </div>
          </div>
          {accounts.length > 0 && (
            <div className="flex-1 bg-gradient-to-br from-violet-500/10 to-[#606C38]/5 border border-violet-500/20 rounded-xl p-4">
              <span className="text-xs font-medium text-violet-600 dark:text-violet-400/80 uppercase tracking-wider">Combined Total (CRC)</span>
              <p className="text-2xl font-bold font-mono tracking-tight text-violet-600 dark:text-violet-400 mt-1">
                {formatAmount(bankCRC + bankUSD * exchangeRate.sell_rate, 'CRC')}
              </p>
            </div>
          )}
        </div>
      )}

      {/* Recent transactions */}
      <div className="bg-surface-card border border-border rounded-xl">
        <div className="flex items-center justify-between px-5 py-4 border-b border-border-subtle">
          <div className="flex items-center gap-2">
            <CreditCard className="w-4 h-4 text-text-muted" />
            <h2 className="font-semibold text-sm">Recent Charges</h2>
          </div>
          <Link
            to="/transactions"
            className="flex items-center gap-1 text-xs font-medium text-[#606C38] dark:text-[#7a8a4a] hover:text-[#4a5a2a] dark:hover:text-[#8a9462] transition-colors"
          >
            View all
            <ArrowRight className="w-3 h-3" />
          </Link>
        </div>
        {recent.length === 0 && !loading ? (
          <div className="px-5 py-12 text-center text-text-faint text-sm">No transactions yet. Add your first one!</div>
        ) : (
          <div className="divide-y divide-border-subtle">
            {recent.map((tx) => (
              <div key={tx.id} className="flex items-center justify-between px-5 py-3.5 hover:bg-surface-hover transition-colors animate-fade-in">
                <div className="flex items-center gap-3 min-w-0">
                  <div className={`w-8 h-8 rounded-lg flex items-center justify-center flex-shrink-0 ${
                    tx.transaction_type === 'DEVOLUCION' ? 'bg-[#606C38]/10 text-[#606C38] dark:text-[#7a8a4a]' : 'bg-red-500/10 text-red-500 dark:text-red-400'
                  }`}>
                    {tx.transaction_type === 'DEVOLUCION' ? <TrendingUp className="w-4 h-4" /> : <TrendingDown className="w-4 h-4" />}
                  </div>
                  <div className="min-w-0">
                    <p className="text-sm font-medium truncate">{tx.merchant}</p>
                    <p className="text-xs text-text-muted">
                      {formatDate(tx.date)}
                      {tx.category && <span className="ml-2 text-text-faint">{tx.category.name}</span>}
                    </p>
                  </div>
                </div>
                <span className={`font-mono text-sm font-medium flex-shrink-0 ml-4 ${
                  tx.transaction_type === 'DEVOLUCION' ? 'text-[#606C38] dark:text-[#7a8a4a]' : ''
                }`}>
                  {tx.transaction_type === 'DEVOLUCION' ? '+' : '-'}{formatAmount(tx.amount, tx.currency)}
                </span>
              </div>
            ))}
          </div>
        )}
      </div>
    </div>
  );
}
