import React, { useEffect, useState } from "react"
import { CirclePlus, Trash, Send } from "lucide-react"
import { useNavigate } from "react-router-dom"
import { ss58Decode } from "@polkadot-labs/hdkd-helpers"

import {
    Accordion,
    AccordionContent,
    AccordionItem,
    AccordionTrigger,
} from "../components/ui/accordion"
import { Input } from "../components/ui/input"
import { Button } from "../components/ui/button"

type AddressBookRecord = {
    name: string
    address: string
}

interface AddressRecordProps {
    name: string
    address: string
    removeRecord: ({ name }: { name: string}) => void
    openTransfer: ({ address }: { address: string}) => void
}

const AddressRecord: React.FC<AddressRecordProps> = ({ name, address, removeRecord, openTransfer }) => {
    return (
        <AccordionItem className="bg-muted rounded px-4" value={name}>
            <AccordionTrigger className="w-full hover:no-underline">
                <div className="w-[90%] sm:text-base text-xs overflow-hidden whitespace-nowrap overflow-ellipsis text-left">
                    {name}
                </div>
            </AccordionTrigger>
            <AccordionContent className="flex flex-row gap-4">
                <Button
                    variant="secondary"
                    size="full"
                    className="flex-1 text-accent flex text-xs sm:flex hidden"
                    onClick={() => openTransfer({ address })}
                >
                    <Send className="w-4 h-4 mr-1" />
                </Button>
                <Input
                    readOnly
                    value={address}
                    aria-label={name}
                    type="text"
                    className="sm:w-[300px] flex-6"
                />
                <Button
                    variant="destructive"
                    size="full"
                    className="flex-2 text-accent text-xs sm:flex hidden"
                    onClick={() => removeRecord({ name })}
                >
                    <Trash className="w-4 h-4 mr-2" />
                    Remove
                </Button>
            </AccordionContent>
        </AccordionItem>
    )
}

export const AddressBook = () => {
    const navigate = useNavigate()

    const [name, setName] = useState<string>("")
    const [address, setAddress] = useState<string>("")
    const [error, setError] = useState<string | undefined>(undefined)
    const [addressBook, setAddressBook] = useState<AddressBookRecord[]>(
        JSON.parse(localStorage.getItem('addressBook') ?? '[]') || []
    )

    useEffect(() => {
        localStorage.setItem('addressBook', JSON.stringify(addressBook))
        setAddress("")
        setName("")
        setError(undefined)
    }, [addressBook])

    const addRecord = ({ name, address }: AddressBookRecord) => {
        if (addressBook.find(record => record.name === name)) {
            setError("Name already exist in the address book")
            return
        }
        if (addressBook.find(record => record.address === address)) {
            setError("Address already exist in the address book")
            return
        }
        try {
            const [, prefix] = ss58Decode(address)
            if (prefix !== 1995 && prefix !== 1996) {
                throw new Error("bad prefix")
            }
        } catch (e) {
            setError("Incorrect Ghost or Casper address provided")
            return
        }
        const newRecord = { name, address }
        setAddressBook([...addressBook, newRecord])
    }

    const removeRecord = ({ name }: { name: string }) => {
        const updatedAddressBook = addressBook.filter((record: AddressBookRecord) =>
            record.name !== name
        )
        setAddressBook(updatedAddressBook)
    }

    const openTransfer = ({ address }: { address: string }) => {
        const queryString = new URLSearchParams({ address }).toString()
        navigate(`/transactions?${queryString}`)
    }

    return (
        <Accordion type="multiple" className="sm:w-[500px] w-[85%] h-fit flex flex-col flex-1 gap-4 justify-center self-center py-2">
            {addressBook.map(({ name, address }: AddressBookRecord, idx: number) => (
                <AddressRecord
                    key={idx}
                    name={name}
                    address={address}
                    removeRecord={removeRecord}
                    openTransfer={openTransfer}
                />
            ))}
            <div className="bg-muted flex flex-col sm:gap-2 gap-4 w-full rounded px-4 py-6">
                <div className="flex sm:flex-row flex-col gap-4">
                    <Input
                        value={name}
                        onChange={e => setName(e.target.value)}
                        aria-label="New Name"
                        type="text"
                        className="w-full sm:text-base text-xs sm:placeholder:text-base placeholder:text-xs"
                        placeholder="Contact Name"
                    />
                    <Input
                        value={address}
                        onChange={e => setAddress(e.target.value)}
                        aria-label="New Address"
                        type="text"
                        className="w-full sm:text-base text-xs sm:placeholder:text-base placeholder:text-xs"
                        placeholder="Contact Address"
                    />
                </div>
                <Button
                    variant="secondary"
                    size="full"
                    className="flex flex-row justify-center items-center"
                    onClick={() => addRecord({ name, address })}
                >
                    <CirclePlus className="w-4 h-4 mr-2" />
                    Add Contact
                </Button>
                {error && (
                    <div className="text-xs text-destructive">{error}</div>
                )}
            </div>
        </Accordion>
    )
}
