"use client"

import { useState, useEffect, useRef }        from "react";
import { Button }                             from "@/components/ui/button";
import { Input }                              from "@/components/ui/input";
import { Textarea }                           from "@/components/ui/textarea"
import { InputGroup, InputGroupAddon }        from "@/components/ui/input-group";
import { InputGroupInput, InputGroupText }    from "@/components/ui/input-group";
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
import { DialogDescription, DialogFooter }    from "@/components/ui/dialog";
import { DialogHeader, DialogTrigger }        from "@/components/ui/dialog";
import { Drawer, DrawerClose, DrawerContent } from "@/components/ui/drawer";
import { DrawerDescription, DrawerFooter }    from "@/components/ui/drawer";
import { DrawerHeader, DrawerTitle }          from "@/components/ui/drawer";
import { DrawerTrigger }                      from "@/components/ui/drawer";
import { Label }                              from "@/components/ui/label";
import { Switch }                             from "@/components/ui/switch";
import { Plus, Download, CircleQuestionMark, Check, ChevronsUpDown } from "lucide-react";
import { Trash2 }     from "lucide-react";
import { toast }                              from "sonner";
import { cn }                                 from "@/lib/utils";
import Link                                   from 'next/link';
import { useMediaQuery }                      from '@/hooks/use-media-query';
import { currencies } from '@/lib/data/currencies';

interface Wallet {
  currency: string
  amount: number
}

function AccountForm({ 
  className,
  wallets,
  addWallet,
  removeWallet,
  updateWallet,
  accountType,
  setAccountType,
}: { 
  className?: string;
  wallets: Wallet[];
  addWallet: () => void;
  removeWallet: (index: number) => void;
  updateWallet: (index: number, field: keyof Wallet, value: string | number) => void;
  accountType: "LIVE" | "DEMO";
  setAccountType: (type: "LIVE" | "DEMO") => void;
}) {
  const usedCurrencies = new Set(wallets.map(b => b.currency));
  const [openComboboxIndex, setOpenComboboxIndex] = useState<number | null>(null);

  return (
    <div className={cn("grid gap-4 py-4", className)}>
      <div className="pb-3">
        <div className="flex items-center space-x-2 pb-2">
          <Switch
            id="type"
            checked={accountType === "LIVE"}
            onCheckedChange={(checked) => setAccountType(checked ? "LIVE" : "DEMO")}
          />
          <Label htmlFor="type">Live account</Label>
        </div>
        <p className="text-sm text-gray-600">Turn this off if demo account.</p>
      </div>
      <div className="grid gap-2">
        <Label htmlFor="name">Name</Label>
        <Input id="name" name="name" required placeholder="e.g. Main Trading" />
      </div>
      <div className="grid gap-2">
        <Label htmlFor="broker">Broker</Label>
        <Input id="broker" name="broker" placeholder="e.g. Interactive Brokers" />
      </div>

      <div className="space-y-3">
        <Label>Wallets</Label>
        <p className="text-sm text-gray-600">Select currency and initial balance</p>
        {wallets.map((wallet, index) => (
          <div key={wallet.currency} className="flex items-center">
            <InputGroup>
              <InputGroupInput
                defaultValue={wallet.amount}
                type="number"
                onChange={(e) => updateWallet(index, "amount", +e.target.value)}
                placeholder="0.00"
                className="flex-1"
                step="0.1"
                required
              />
              <InputGroupAddon>
                <Popover open={openComboboxIndex === index} onOpenChange={(open) => setOpenComboboxIndex(open ? index : null)}>
                  <PopoverTrigger asChild>
                    <Button
                      variant="outline"
                      role="combobox"
                      aria-expanded={openComboboxIndex === index}
                      className="bg-transparent focus:bg-transparent hover:bg-transparent cursor-pointer py-0! border-0 border-r border-border rounded-none font-normal"
                    >
                      {wallet.currency
                        ? currencies.find((c) => c.code === wallet.currency)?.code
                        : "Select"}
                      <ChevronsUpDown className="ml-2 h-4 w-4 shrink-0 opacity-50" />
                    </Button>
                  </PopoverTrigger>
                  <PopoverContent className="w-50 p-0" align="end">
                    <Command>
                      <CommandInput placeholder="Search..." />
                      <CommandList>
                        <CommandEmpty>No currency found.</CommandEmpty>
                        <CommandGroup>
                          {currencies.map((currency) => (
                            <CommandItem
                              className="cursor-pointer"
                              key={currency.code}
                              value={currency.code}
                              onSelect={(currentValue) => {
                                const selectedCode = currencies.find(c => c.code.toLowerCase() === currentValue.toLowerCase())?.code || currentValue.toUpperCase();
                                updateWallet(index, "currency", selectedCode)
                                setOpenComboboxIndex(null)
                              }}
                              disabled={usedCurrencies.has(currency.code) && currency.code !== wallet.currency}
                            >
                              <Check
                                className={cn(
                                  "mr-0 h-4 w-4",
                                  wallet.currency === currency.code ? "opacity-100" : "opacity-0"
                                )}
                              />
                              <span className="text-muted-foreground">
                                {`${currency.code}`}
                              </span>
                              <span className="text-sm truncate">
                                {currency.name}
                              </span>
                            </CommandItem>
                          ))}
                        </CommandGroup>
                      </CommandList>
                    </Command>
                  </PopoverContent>
                </Popover>
              </InputGroupAddon>
            </InputGroup>
            {wallets.length > 1 && (
              <Button
                type="button"
                variant="ghost"
                size="icon"
                onClick={() => removeWallet(index)}
                title="Remove"
                className="bg-transparent hover:bg-transparent focus:bg-transparent cursor-pointer rounded-full opacity-80 text-destructive hover:text-destructive"
              >
                <Trash2 className="h-4 w-4" />
              </Button>
            )}
          </div>
        ))}
        <Button type="button" variant="outline" size="sm" onClick={addWallet} disabled={usedCurrencies.size >= currencies.length} className="w-full border-dashed cursor-pointer">
          <Plus className="mr-1 h-4 w-4" /> Add Wallet
        </Button>
      </div>
    </div>
  )
}

export function TradesHeader({
  setNewAccountsAction,
}: {
  setNewAccountsAction: (account: any) => void;
}) {
  const [open, setOpen] = useState(false);
  const [isFormValid, setIsFormValid] = useState(false);
  const [loading, setLoading] = useState(false);
  const mq = useMediaQuery();
  const [wallets, setWallets] = useState<Wallet[]>([{ currency: "NGN", amount: 0 }]);
  const [accountType, setAccountType] = useState<"LIVE" | "DEMO">("LIVE");

  const addWallet = () => {
    const used = new Set(wallets.map(b => b.currency));
    const next = currencies.find(c => !used.has(c.code));
    if (next) {
      setWallets([...wallets, { currency: next.code, amount: 0 }]);
    }
  }

  const removeWallet = (index: number) => {
    if (wallets.length > 1) {
      const removedCurrency = wallets[index].currency;
      const newWallets = wallets.filter((_, i) => i !== index);
      setWallets(newWallets);
    }
  }

  const updateWallet = (index: number, field: keyof Wallet, value: string | number) => {
    const newWallets = [...wallets]
    const oldCurrency = newWallets[index].currency;
    // @ts-ignore
    newWallets[index] = { ...newWallets[index], [field]: value }
    setWallets(newWallets);
  }

  const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault()
    setLoading(true)

    const formData = new FormData(e.currentTarget)
    
    const walletsRecord: Record<string, number> = {};
    wallets.forEach(b => {
        walletsRecord[b.currency] = b.amount;
    });

    const data = {
      name: formData.get("name"),
      broker: formData.get("broker"),
      type: accountType,
      wallets: walletsRecord,
    }

    try {
      const response = await fetch("/api/user/accounts/new", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(data),
      })

      if (!response.ok) throw new Error("Failed to create account");

      toast.success("Account created successfully");
      setOpen(false);
      setWallets([{ currency: "NGN", amount: 0 }]);
      setAccountType("LIVE");
      
      setNewAccountsAction((p: any[]) => {
        return [
          {
            ...data,
            id: 'temp-' + Date.now(),
            wallets: wallets.map(b => ({
              currency: b.currency,
              initial: b.amount,
              current: b.amount,
              createdAt: new Date(), // TODO: change to ISO string
              updatedAt: new Date(), // TODO: change to ISO string
            }))
          },
          ...p
        ];
      });
    } catch (error) {
      toast.error("Failed to create account")
    } finally {
      setLoading(false)
    }
  }

  return (
    <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
      <div>
        <h1 className="text-3xl font-bold tracking-tight">Accounts</h1>
        <p className="text-muted-foreground">Manage your trading accounts</p>
      </div>
      <div className="flex gap-2">
        {mq?.desktop ? (
          <Dialog open={open} onOpenChange={setOpen}>
            <DialogTrigger asChild>
              <Button className="flex items-center gap-1 cursor-pointer">
                <Plus className="h-4 w-4" />
                Add New
              </Button>
            </DialogTrigger>
            <DialogContent showCloseButton={false} className="sm:max-w-106.25 overflow-hidden max-h-[calc(100vh-2.5rem)] flex flex-col px-0! pb-0! gap-0">
              <div className="flex-1 overflow-y-auto px-6">
                <DialogHeader className="pb-6">
                  <DialogTitle>Add New Account</DialogTitle>
                  <DialogDescription>
                    Create a new trading account. You can add multiple wallets each with an initial balance.
                  </DialogDescription>
                </DialogHeader>
                <form id="new-account-dialog" onSubmit={handleSubmit} onChange={(e) => setIsFormValid(e.currentTarget.checkValidity())} className="pb-4">
                  <AccountForm
                    wallets={wallets}
                    addWallet={addWallet}
                    removeWallet={removeWallet}
                    updateWallet={updateWallet}
                    accountType={accountType}
                    setAccountType={setAccountType}
                  />
                </form>
              </div>
              <div className="px-6 py-4 flex justify-between items-center gap-3 border-t border-border">
                <div className="">
                  <Button asChild type="button" variant="ghost" size="icon" className="bg-transparent hover:bg-transparent w-auto h-auto p-1 rounded-full text-gray-600">
                    <Link href="#" target="_blank">
                      <CircleQuestionMark />
                    </Link>
                  </Button>
                </div>
                <div className="inline-flex gap-3">
                  <Button className="cursor-pointer" variant="outline" type="button" onClick={() => setOpen(false)}>Cancel</Button>
                  <Button className="cursor-pointer" type="submit" form="new-account-dialog" disabled={!isFormValid}>Add Account</Button>
                </div>
              </div>
            </DialogContent>
          </Dialog>
        ) : (
          <Drawer open={open} onOpenChange={setOpen}>
            <DrawerTrigger asChild>
              <Button className="flex items-center gap-1 cursor-pointer">
                <Plus className="h-4 w-4" />
                Add New
              </Button>
            </DrawerTrigger>
            <DrawerContent className="h-auto! max-h-[98vh]!">
              <form id="add-account-form" onSubmit={handleSubmit} onChange={(e) => setIsFormValid(e.currentTarget.checkValidity())} className="block overflow-y-auto px-4 pb-6">
                <DrawerHeader className="text-left pb-6">
                  <DrawerTitle>Add New Account</DrawerTitle>
                  <DrawerDescription>
                    Create a new trading account. You can add multiple wallets each with an initial balance.
                  </DrawerDescription>
                </DrawerHeader>
                <AccountForm
                  wallets={wallets}
                  addWallet={addWallet}
                  removeWallet={removeWallet}
                  updateWallet={updateWallet}
                  accountType={accountType}
                  setAccountType={setAccountType}
                />
              </form>
              <DrawerFooter className="grid grid-cols-2 gap-3 border-t border-border py-3">
                <DrawerClose asChild>
                  <Button className="cursor-pointer" variant="outline">Cancel</Button>
                </DrawerClose>
                <Button className="cursor-pointer" type="submit" form="add-account-form" disabled={!isFormValid}>Add Account</Button>
              </DrawerFooter>
            </DrawerContent>
          </Drawer>
        )}
      </div>
    </div>
  )
}
