"use client"

import React from 'react'
import { useDebounce } from '@/hooks/useDebounce';
import { useLoading } from '@/lib/useLoading';
import { deleteToken, getToken, updateToken } from '@/actions/ttd';
import {
    Card,
    CardContent,
    CardDescription,
    CardHeader,
    CardTitle,
} from "@/components/ui/card"
import { toast } from 'sonner';
import AddToken from './add-token';
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { CopyIcon, Search, XIcon } from 'lucide-react';
import DataTable from '@/components/table/data-table';
import { ColumnDef } from '@tanstack/react-table';
import DeleteDialog from '@/components/delete/delete-dialog';
import UpdateToken from './update-token';
import moment from 'moment-timezone';

const ListToken = () => {
    const [tokens, setTokens] = React.useState<any[]>([]);
    const [offset, setOffset] = React.useState(0);
    const [hasMore, setHasMore] = React.useState(true);
    const [search, setSearch] = React.useState('');
    const [page, setPage] = React.useState<any | null>(null);
    const debouncedSearch = useDebounce(search, 500);
    const {loading, setLoading} = useLoading();

    const fetchData = async ({ value = debouncedSearch, skip = offset }: { value?: string, skip?: number }) => {
        if(loading) setLoading(true)
        setLoading(true);
        const response = await getToken(skip, value);
        if(response.success){
            setTokens(response.data);
            setHasMore(response.hasMore)
            setPage({
                page : response.currentPage,
                allPage: response.totalPages,
                total: response.total
            })
        }else{
            setHasMore(false);
            setPage({
                page : response.currentPage,
                allPage: response.totalPages,
                total: response.total
            })
            if (offset === 0) setTokens([]);
            toast.error(response.message);
        }
        setLoading(false);
    }

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

    const handleSearchChange = (e: React.ChangeEvent<HTMLInputElement>) => {
        setSearch(e.target.value);
        setOffset(0)
    };

    const nextPage = () => {
        if (hasMore) {
            const skip = offset + 10;
            setOffset(skip)
            fetchData({ skip }); 
        }
    }

    const prevPage = () => {
        const skip = Math.max(0, offset - 10)
        setOffset(skip)
        fetchData({ skip })
    }

    const clearSearch = () => {
        setSearch("")
        fetchData({ value: ""})
    }

    const columns: ColumnDef<any>[] = [
        {
            accessorKey: 'name',
            header: () => <span className='font-bold'>TOKEN NAME</span>,
            enableSorting: true,
            enableColumnFilter: false,
            enableGlobalFilter: true,
            cell: (info: any) => {
                const row = info.row.original;
                return <p className='w-fit'>{row.name}</p>
            },
        },
        {
            accessorKey: 'token',
            header: () => <span className='font-bold'>TOKEN</span>,
            enableSorting: true,
            enableColumnFilter: false,
            enableGlobalFilter: true,
            cell: (info: any) => {
                const row = info.row.original;
                return (
                    <div className='flex items-center'>
                        <p className='w-fit'>{row.token.slice(0, 50)}...</p>
                        <Button size="sm" variant="ghost" onClick={() => copyToClipboard(row.token)}>
                            <CopyIcon />
                        </Button>
                    </div>
                )
            },
        },
        {
            accessorKey: 'updatedAt',
            header: () => <span className='font-bold'>LAST UPDATE</span>,
            enableSorting: true,
            enableColumnFilter: false,
            enableGlobalFilter: true,
            cell: (info: any) => {
                const row = info.row.original;
                return <p>{moment(row.updatedAt).tz("Asia/Makassar").fromNow()}</p>
            },
        },
        {
            accessorKey: 'action',
            header: () => <span className='font-bold'>Action</span>,
            enableSorting: false,
            enableColumnFilter: false,
            cell: (info: any) => {
                const row = info.row.original;
                return (
                    <div className='flex items-center gap-2'>
                        <UpdateToken
                            onUpdate={() => handleUpdate(row._id, row.name)}
                        />
                        <DeleteDialog 
                            onDelete={() => handleDelete(row._id)}
                        />
                    </div>
                );
            },
        },
    ]

    const handleUpdate = async (id: string, name: string) => {
        setLoading(true)
        const response = await updateToken(id ,{name})
        if(response.success){
            toast.success(response.message)
            fetchData({})
        }else{
            toast.error(response.message)
        }
        setLoading(false)
    }

    const handleDelete = async (id: string) => {
        setLoading(true)
        const response = await deleteToken(id)
        if(response.success){
            toast.success(response.message)
            fetchData({})
        }else{
            toast.error(response.message)
        }
        setLoading(false)
    }

    const copyToClipboard = (text: string) => {
        navigator.clipboard
        .writeText(text)
        .then(() => {
            toast.success("Copied to clipboard!");
        })
        .catch(() => {
            toast.error("Failed to copy!");
        });
    };
    return (
        <div className="grid grid-cols-3 gap-6">
            <Card className='h-fit'>
                <CardHeader>
                    <CardTitle>Generate New Token</CardTitle>
                    <CardDescription>Create a new token to grant API access with specific permissions.</CardDescription>
                </CardHeader>
                <CardContent>
                    <AddToken onAction={() => fetchData({})}/>
                </CardContent>
            </Card>
            <div className='col-span-2'>
                <Card>
                    <CardHeader>
                        <CardTitle>API Access Tokens</CardTitle>
                        <CardDescription>Manage the list of tokens used to access the API.</CardDescription>
                    </CardHeader>
                    <CardContent className='space-y-6'>
                        <div className='flex items-center justify-between'>
                            <div className='flex items-center gap-3'>
                                <div className="relative max-w-2xs">
                                    <Input
                                        type="text"
                                        value={search}
                                        placeholder="Search token..."
                                        className="border px-2 py-1 rounded-lg"
                                        onChange={handleSearchChange}
                                        onKeyDown={(e) => {
                                            if (e.key === 'Enter') {
                                                fetchData({ value: search })
                                            }
                                        }}
                                    />
                                    {search && (
                                        <div className="absolute top-2 right-2 translate translate-y-0">
                                            <Button 
                                                type="button" 
                                                variant="black" 
                                                size="bullet" 
                                                onClick={clearSearch}
                                            >
                                                <XIcon />
                                            </Button>
                                        </div>
                                    )}
                                </div>
                                <Button 
                                    size="rounded"
                                    onClick={() => {
                                        if(!search) return;
                                        fetchData({ value: search })
                                    }}
                                >
                                    <Search />
                                </Button>
                            </div>
                            <div className="flex items-center gap-3">
                                <Button variant="green" onClick={() => fetchData({})}>
                                    Refresh Data
                                </Button>
                            </div>
                        </div>
                        <DataTable 
                            data={tokens}
                            columns={columns}
                            isLoading={loading}
                            next={nextPage}
                            prev={prevPage}
                            canNextpage={!hasMore}
                            canPrevPage={offset === 0}
                            page={page?.page || 0}
                            allPage={page?.allPage || 0}
                            total={page?.total || 0}
                        />
                    </CardContent>
                </Card>
            </div>
        </div>
    )
}

export default ListToken