import {
  useActionMutation,
  useActionQuery,
} from "@agent-native/core/client/hooks";
import { useT } from "@agent-native/core/client/i18n";
import { useSetPageTitle } from "@agent-native/toolkit/app-shell";
import { IconPlus, IconStar, IconStarFilled, IconTrash } from "@tabler/icons-react";
import { useMemo, useState } from "react";
import { toast } from "sonner";

import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Card, CardContent } from "@/components/ui/card";
import {
  Dialog,
  DialogContent,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from "@/components/ui/table";
import { APP_TITLE } from "@/lib/app-config";
import { cn } from "@/lib/utils";

export function meta() {
  return [{ title: `Stocks - ${APP_TITLE}` }];
}

interface StockFormState {
  symbol: string;
  companyName: string;
  exchange: string;
  sector: string;
  currency: string;
  price: string;
  changePercent: string;
  marketCap: string;
}

const EMPTY_FORM: StockFormState = {
  symbol: "",
  companyName: "",
  exchange: "NASDAQ",
  sector: "",
  currency: "USD",
  price: "",
  changePercent: "",
  marketCap: "",
};

function formatMoney(value: number, currency: string) {
  try {
    return new Intl.NumberFormat(undefined, {
      style: "currency",
      currency,
      maximumFractionDigits: 2,
    }).format(value);
  } catch {
    return `${value.toFixed(2)} ${currency}`;
  }
}

function formatMarketCap(value: number | null) {
  if (value === null || value === undefined) return "—";
  if (value >= 1_000_000_000_000) return `${(value / 1_000_000_000_000).toFixed(2)}T`;
  if (value >= 1_000_000_000) return `${(value / 1_000_000_000).toFixed(2)}B`;
  if (value >= 1_000_000) return `${(value / 1_000_000).toFixed(2)}M`;
  return String(value);
}

function AddStockDialog() {
  const [open, setOpen] = useState(false);
  const [form, setForm] = useState<StockFormState>(EMPTY_FORM);
  const addStock = useActionMutation("add-stock", {
    onSuccess: () => {
      toast.success(`${form.symbol.toUpperCase()} added`);
      setForm(EMPTY_FORM);
      setOpen(false);
    },
    onError: (error) => toast.error(error.message),
  });

  function submit() {
    if (!form.symbol.trim() || !form.companyName.trim()) {
      toast.error("Symbol and company name are required.");
      return;
    }
    addStock.mutate({
      symbol: form.symbol.trim(),
      companyName: form.companyName.trim(),
      exchange: form.exchange.trim() || "NASDAQ",
      sector: form.sector.trim() || undefined,
      currency: form.currency.trim() || "USD",
      price: form.price ? Number(form.price) : 0,
      changePercent: form.changePercent ? Number(form.changePercent) : 0,
      marketCap: form.marketCap ? Number(form.marketCap) : undefined,
    });
  }

  return (
    <Dialog open={open} onOpenChange={setOpen}>
      <DialogTrigger asChild>
        <Button size="sm" className="gap-1.5">
          <IconPlus className="size-4" />
          Add stock
        </Button>
      </DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Add stock</DialogTitle>
        </DialogHeader>
        <div className="grid grid-cols-2 gap-3">
          <div className="col-span-2 space-y-1.5">
            <Label htmlFor="symbol">Symbol</Label>
            <Input
              id="symbol"
              placeholder="AAPL"
              value={form.symbol}
              onChange={(e) => setForm({ ...form, symbol: e.target.value })}
            />
          </div>
          <div className="col-span-2 space-y-1.5">
            <Label htmlFor="companyName">Company name</Label>
            <Input
              id="companyName"
              placeholder="Apple Inc."
              value={form.companyName}
              onChange={(e) => setForm({ ...form, companyName: e.target.value })}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="exchange">Exchange</Label>
            <Input
              id="exchange"
              value={form.exchange}
              onChange={(e) => setForm({ ...form, exchange: e.target.value })}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="sector">Sector</Label>
            <Input
              id="sector"
              placeholder="Technology"
              value={form.sector}
              onChange={(e) => setForm({ ...form, sector: e.target.value })}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="price">Price</Label>
            <Input
              id="price"
              type="number"
              inputMode="decimal"
              value={form.price}
              onChange={(e) => setForm({ ...form, price: e.target.value })}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="changePercent">Change %</Label>
            <Input
              id="changePercent"
              type="number"
              inputMode="decimal"
              value={form.changePercent}
              onChange={(e) =>
                setForm({ ...form, changePercent: e.target.value })
              }
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="currency">Currency</Label>
            <Input
              id="currency"
              value={form.currency}
              onChange={(e) => setForm({ ...form, currency: e.target.value })}
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="marketCap">Market cap</Label>
            <Input
              id="marketCap"
              type="number"
              inputMode="decimal"
              value={form.marketCap}
              onChange={(e) => setForm({ ...form, marketCap: e.target.value })}
            />
          </div>
        </div>
        <DialogFooter>
          <Button onClick={submit} disabled={addStock.isPending}>
            {addStock.isPending ? "Adding…" : "Add stock"}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

interface StockRow {
  id: string;
  symbol: string;
  companyName: string;
  exchange: string;
  sector: string | null;
  currency: string;
  price: number;
  changePercent: number;
  marketCap: number | null;
  watchlisted: boolean;
}

function ChangeBadge({ value }: { value: number }) {
  const positive = value > 0;
  const negative = value < 0;
  return (
    <Badge
      variant="outline"
      className={cn(
        "font-mono tabular-nums",
        positive && "border-emerald-500/40 text-emerald-600 dark:text-emerald-400",
        negative && "border-red-500/40 text-red-600 dark:text-red-400",
      )}
    >
      {positive ? "+" : ""}
      {value.toFixed(2)}%
    </Badge>
  );
}

function WatchlistButton({ stock }: { stock: StockRow }) {
  const toggle = useActionMutation("update-stock", {
    method: "PUT",
    onError: (error) => toast.error(error.message),
  });
  return (
    <Button
      variant="ghost"
      size="icon"
      className="size-8"
      aria-label={stock.watchlisted ? "Remove from watchlist" : "Add to watchlist"}
      disabled={toggle.isPending}
      onClick={() =>
        toggle.mutate({
          id: stock.id,
          watchlisted: stock.watchlisted ? "false" : "true",
        })
      }
    >
      {stock.watchlisted ? (
        <IconStarFilled className="size-4 text-amber-500" />
      ) : (
        <IconStar className="size-4 text-muted-foreground" />
      )}
    </Button>
  );
}

function DeleteStockButton({ stock }: { stock: StockRow }) {
  const del = useActionMutation("delete-stock", {
    method: "DELETE",
    onSuccess: () => toast.success(`${stock.symbol} removed`),
    onError: (error) => toast.error(error.message),
  });
  return (
    <Button
      variant="ghost"
      size="icon"
      className="size-8 text-muted-foreground hover:text-destructive"
      aria-label={`Delete ${stock.symbol}`}
      disabled={del.isPending}
      onClick={() => {
        if (window.confirm(`Remove ${stock.symbol} from your listings?`)) {
          del.mutate({ id: stock.id });
        }
      }}
    >
      <IconTrash className="size-4" />
    </Button>
  );
}

export default function StocksRoute() {
  const t = useT();
  useSetPageTitle(t("navigation.stocks"));
  const [search, setSearch] = useState("");
  const { data, isLoading } = useActionQuery("list-stocks", {
    search: search || undefined,
  });
  const stocks = useMemo(() => (data?.stocks ?? []) as StockRow[], [data]);

  return (
    <div className="mx-auto flex w-full max-w-4xl flex-col gap-4 p-4 sm:p-6">
      <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
        <div>
          <h1 className="text-lg font-semibold tracking-tight">
            {t("navigation.stocks")}
          </h1>
          <p className="text-sm text-muted-foreground">
            {t("pages.stocksDescription")}
          </p>
        </div>
        <AddStockDialog />
      </div>

      <Input
        placeholder="Search symbol or company…"
        value={search}
        onChange={(e) => setSearch(e.target.value)}
        className="sm:max-w-xs"
      />

      {isLoading ? (
        <p className="py-8 text-center text-sm text-muted-foreground">Loading…</p>
      ) : stocks.length === 0 ? (
        <Card>
          <CardContent className="py-10 text-center text-sm text-muted-foreground">
            No stocks listed yet. Add one, or ask the agent to add some.
          </CardContent>
        </Card>
      ) : (
        <>
          {/* Mobile: stacked cards */}
          <div className="flex flex-col gap-2 sm:hidden">
            {stocks.map((stock) => (
              <Card key={stock.id}>
                <CardContent className="flex items-center gap-3 py-3">
                  <div className="min-w-0 flex-1">
                    <div className="flex items-center gap-2">
                      <span className="font-semibold">{stock.symbol}</span>
                      <span className="truncate text-xs text-muted-foreground">
                        {stock.exchange}
                      </span>
                    </div>
                    <p className="truncate text-sm text-muted-foreground">
                      {stock.companyName}
                    </p>
                    <div className="mt-1 flex items-center gap-2">
                      <span className="font-mono text-sm tabular-nums">
                        {formatMoney(stock.price, stock.currency)}
                      </span>
                      <ChangeBadge value={stock.changePercent} />
                    </div>
                  </div>
                  <WatchlistButton stock={stock} />
                  <DeleteStockButton stock={stock} />
                </CardContent>
              </Card>
            ))}
          </div>

          {/* Desktop: table */}
          <div className="hidden overflow-x-auto rounded-md border sm:block">
            <Table>
              <TableHeader>
                <TableRow>
                  <TableHead className="w-8" />
                  <TableHead>Symbol</TableHead>
                  <TableHead>Company</TableHead>
                  <TableHead>Exchange</TableHead>
                  <TableHead>Sector</TableHead>
                  <TableHead className="text-right">Price</TableHead>
                  <TableHead className="text-right">Change</TableHead>
                  <TableHead className="text-right">Market Cap</TableHead>
                  <TableHead className="w-8" />
                </TableRow>
              </TableHeader>
              <TableBody>
                {stocks.map((stock) => (
                  <TableRow key={stock.id}>
                    <TableCell>
                      <WatchlistButton stock={stock} />
                    </TableCell>
                    <TableCell className="font-semibold">{stock.symbol}</TableCell>
                    <TableCell className="max-w-52 truncate text-muted-foreground">
                      {stock.companyName}
                    </TableCell>
                    <TableCell className="text-muted-foreground">
                      {stock.exchange}
                    </TableCell>
                    <TableCell className="text-muted-foreground">
                      {stock.sector ?? "—"}
                    </TableCell>
                    <TableCell className="text-right font-mono tabular-nums">
                      {formatMoney(stock.price, stock.currency)}
                    </TableCell>
                    <TableCell className="text-right">
                      <ChangeBadge value={stock.changePercent} />
                    </TableCell>
                    <TableCell className="text-right text-muted-foreground">
                      {formatMarketCap(stock.marketCap)}
                    </TableCell>
                    <TableCell>
                      <DeleteStockButton stock={stock} />
                    </TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </div>
        </>
      )}
    </div>
  );
}
