import { useState } from "react";
import { Link } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { getAccounts, createAccount, updateAccount, deleteAccount, getNetWorth, type Account } from "@/api/accounts";
import { getPortfolio } from "@/api/investments";
import { formatCurrency } from "@/utils/currency";
import { cn } from "@/utils/cn";
import {
  Plus, Trash2, Pencil, TrendingUp, Wallet,
  CreditCard, PiggyBank, Building2, Coins, Bitcoin, Landmark, ShieldCheck, Sprout
} from "lucide-react";
import AccountFormModal from "./AccountFormModal";

const TYPE_ICONS: Record<string, React.ElementType> = {
  checking: Wallet,
  savings: PiggyBank,
  cash_isa: Sprout,
  stocks_shares_isa: TrendingUp,
  credit_card: CreditCard,
  investment: TrendingUp,
  cash: Coins,
  crypto_wallet: Bitcoin,
  loan: Building2,
  mortgage: Landmark,
  pension: ShieldCheck,
  other: Wallet,
};

const TYPE_LABELS: Record<string, string> = {
  checking: "Checking",
  savings: "Savings",
  cash_isa: "Cash ISA",
  stocks_shares_isa: "S&S ISA",
  credit_card: "Credit Card",
  investment: "Investment",
  cash: "Cash",
  crypto_wallet: "Crypto",
  loan: "Loan",
  mortgage: "Mortgage",
  pension: "Pension",
  other: "Other",
};

const LIABILITY_TYPES = new Set(["credit_card", "loan", "mortgage"]);

export default function AccountList() {
  const qc = useQueryClient();
  const [showCreate, setShowCreate] = useState(false);
  const [editing, setEditing] = useState<Account | null>(null);

  const { data: accounts = [], isLoading } = useQuery({
    queryKey: ["accounts"],
    queryFn: getAccounts,
  });

  const { data: nw } = useQuery({
    queryKey: ["net-worth"],
    queryFn: getNetWorth,
  });

  const { data: portfolio } = useQuery({
    queryKey: ["portfolio"],
    queryFn: getPortfolio,
  });

  const holdingValueByAccount = (portfolio?.holdings ?? []).reduce<Record<string, number>>((acc, h) => {
    const v = Number(h.current_value || h.cost_basis_total);
    acc[h.account_id] = (acc[h.account_id] ?? 0) + v;
    return acc;
  }, {});

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ["accounts"] });
    qc.invalidateQueries({ queryKey: ["net-worth"] });
  };

  const deleteMutation = useMutation({
    mutationFn: deleteAccount,
    onSuccess: invalidate,
  });

  const createMutation = useMutation({
    mutationFn: createAccount,
    onSuccess: () => { invalidate(); setShowCreate(false); },
  });

  const updateMutation = useMutation({
    mutationFn: ({ id, data }: { id: string; data: Parameters<typeof updateAccount>[1] }) =>
      updateAccount(id, data),
    onSuccess: () => { invalidate(); setEditing(null); },
  });

  const assets = accounts.filter(a => !LIABILITY_TYPES.has(a.type) && a.is_active);
  const liabilities = accounts.filter(a => LIABILITY_TYPES.has(a.type) && a.is_active);
  const inactive = accounts.filter(a => !a.is_active);

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-2xl font-bold">Accounts</h1>
          <p className="text-sm text-muted-foreground mt-1">Manage your financial accounts</p>
        </div>
        <button
          onClick={() => setShowCreate(true)}
          className="flex items-center gap-2 bg-primary text-primary-foreground px-4 py-2 rounded-lg text-sm font-medium hover:bg-primary/90 transition-colors"
        >
          <Plus className="w-4 h-4" />
          Add Account
        </button>
      </div>

      {nw && (
        <div className="grid grid-cols-1 sm:grid-cols-3 gap-4">
          {[
            { label: "Total Assets", value: nw.total_assets, positive: true },
            { label: "Total Liabilities", value: nw.total_liabilities, positive: nw.total_liabilities === 0 },
            { label: "Net Worth", value: nw.net_worth, positive: nw.net_worth >= 0 },
          ].map(({ label, value, positive }) => (
            <div key={label} className="bg-card border border-border rounded-xl p-4">
              <p className="text-xs text-muted-foreground mb-1">{label}</p>
              <p className={cn("text-xl font-bold", positive ? "text-success" : "text-destructive")}>
                {formatCurrency(value, nw.base_currency)}
              </p>
            </div>
          ))}
        </div>
      )}

      {isLoading && (
        <div className="space-y-2">
          {[1, 2, 3].map(i => (
            <div key={i} className="h-20 bg-card border border-border rounded-xl animate-pulse" />
          ))}
        </div>
      )}

      {assets.length > 0 && (
        <AccountGroup
          title="Assets"
          accounts={assets}
          onEdit={setEditing}
          onDelete={id => deleteMutation.mutate(id)}
          holdingValueByAccount={holdingValueByAccount}
        />
      )}

      {liabilities.length > 0 && (
        <AccountGroup
          title="Liabilities"
          accounts={liabilities}
          onEdit={setEditing}
          onDelete={id => deleteMutation.mutate(id)}
        />
      )}

      {inactive.length > 0 && (
        <AccountGroup
          title="Inactive"
          accounts={inactive}
          onEdit={setEditing}
          onDelete={id => deleteMutation.mutate(id)}
          holdingValueByAccount={holdingValueByAccount}
          muted
        />
      )}

      {accounts.length === 0 && !isLoading && (
        <div className="text-center py-16 text-muted-foreground">
          <Wallet className="w-12 h-12 mx-auto mb-3 opacity-30" />
          <p className="font-medium">No accounts yet</p>
          <p className="text-sm mt-1">Add your first account to get started</p>
        </div>
      )}

      {showCreate && (
        <AccountFormModal
          onClose={() => setShowCreate(false)}
          onSubmit={data => createMutation.mutate(data)}
          isLoading={createMutation.isPending}
        />
      )}

      {editing && (
        <AccountFormModal
          account={editing}
          onClose={() => setEditing(null)}
          onSubmit={data => updateMutation.mutate({ id: editing.id, data })}
          isLoading={updateMutation.isPending}
        />
      )}
    </div>
  );
}

const INVESTMENT_TYPES = new Set(["investment", "pension", "stocks_shares_isa", "crypto_wallet"]);

function AccountGroup({
  title,
  accounts,
  onEdit,
  onDelete,
  holdingValueByAccount = {},
  muted = false,
}: {
  title: string;
  accounts: Account[];
  onEdit: (a: Account) => void;
  onDelete: (id: string) => void;
  holdingValueByAccount?: Record<string, number>;
  muted?: boolean;
}) {
  return (
    <div>
      <h2 className={cn("text-sm font-semibold uppercase tracking-wider mb-3", muted ? "text-muted-foreground" : "text-foreground")}>
        {title}
      </h2>
      <div className="space-y-2">
        {accounts.map(account => {
          const Icon = TYPE_ICONS[account.type] || Wallet;
          const isLiability = LIABILITY_TYPES.has(account.type);
          const utilPct = account.credit_limit && account.credit_limit > 0
            ? Math.min(100, (Math.abs(account.current_balance) / account.credit_limit) * 100)
            : null;

          return (
            <div
              key={account.id}
              className="bg-card border border-border rounded-xl p-4 hover:border-primary/30 transition-colors group"
            >
              <div className="flex items-center gap-4">
                <div className="p-2.5 rounded-lg shrink-0" style={{ backgroundColor: account.color + "20" }}>
                  <Icon className="w-5 h-5" style={{ color: account.color }} />
                </div>

                <div className="flex-1 min-w-0">
                  <div className="flex items-center gap-2 flex-wrap">
                    <Link to={`/accounts/${account.id}`} className="font-medium truncate hover:text-primary transition-colors">
                      {account.name}
                    </Link>
                    <span className="text-xs text-muted-foreground bg-secondary px-1.5 py-0.5 rounded shrink-0">
                      {TYPE_LABELS[account.type] || account.type}
                    </span>
                    {!account.include_in_net_worth && (
                      <span className="text-xs text-muted-foreground italic">excluded from net worth</span>
                    )}
                  </div>
                  <div className="flex items-center gap-3 mt-0.5 flex-wrap">
                    {account.institution && (
                      <p className="text-xs text-muted-foreground">{account.institution}</p>
                    )}
                    {account.interest_rate != null && (
                      <p className="text-xs text-muted-foreground">
                        <span className="font-medium text-foreground">{Number(account.interest_rate).toFixed(2)}%</span> p.a.
                      </p>
                    )}
                    {account.notes && (
                      <p className="text-xs text-muted-foreground truncate max-w-xs">{account.notes}</p>
                    )}
                  </div>
                </div>

                <div className="text-right shrink-0">
                  {(() => {
                    const holdingVal = INVESTMENT_TYPES.has(account.type) ? (holdingValueByAccount[account.id] ?? 0) : 0;
                    const cashBal = Number(account.current_balance);
                    const total = cashBal + holdingVal;
                    return (
                      <>
                        <p className={cn("font-semibold tabular-nums", isLiability ? "text-destructive" : "text-foreground")}>
                          {formatCurrency(holdingVal > 0 ? total : cashBal, account.currency)}
                        </p>
                        {holdingVal > 0 && cashBal !== 0 && (
                          <p className="text-xs text-muted-foreground">
                            {formatCurrency(cashBal, account.currency)} cash + {formatCurrency(holdingVal, account.currency)} holdings
                          </p>
                        )}
                        {holdingVal > 0 && cashBal === 0 && (
                          <p className="text-xs text-muted-foreground">holdings value</p>
                        )}
                        {account.credit_limit != null && (
                          <p className="text-xs text-muted-foreground">
                            limit {formatCurrency(account.credit_limit, account.currency)}
                          </p>
                        )}
                      </>
                    );
                  })()}
                </div>

                <div className="flex items-center gap-1 opacity-100 sm:opacity-0 sm:group-hover:opacity-100 transition-opacity shrink-0">
                  <button
                    onClick={() => onEdit(account)}
                    className="p-1.5 rounded text-muted-foreground hover:text-foreground hover:bg-secondary"
                    title="Edit account"
                  >
                    <Pencil className="w-4 h-4" />
                  </button>
                  <button
                    onClick={() => onDelete(account.id)}
                    className="p-1.5 rounded text-muted-foreground hover:text-destructive hover:bg-destructive/10"
                    title="Delete account"
                  >
                    <Trash2 className="w-4 h-4" />
                  </button>
                </div>
              </div>

              {/* Credit utilisation bar */}
              {utilPct !== null && (
                <div className="mt-3">
                  <div className="flex justify-between text-xs text-muted-foreground mb-1">
                    <span>Credit used</span>
                    <span>{utilPct.toFixed(0)}%</span>
                  </div>
                  <div className="h-1.5 bg-secondary rounded-full overflow-hidden">
                    <div
                      className={cn("h-full rounded-full transition-all", utilPct > 80 ? "bg-destructive" : utilPct > 50 ? "bg-warning" : "bg-success")}
                      style={{ width: `${utilPct}%` }}
                    />
                  </div>
                </div>
              )}
            </div>
          );
        })}
      </div>
    </div>
  );
}
