import {
    Dialog,
    DialogContent,
    DialogHeader,
    DialogTitle,
} from '@/components/ui/dialog';
import { Badge } from '@/components/ui/badge';
import {
    Table,
    TableBody,
    TableCell,
    TableHead,
    TableHeader,
    TableRow,
} from '@/components/ui/table';
import type { FormHistory } from './columns';

type AttributeChangesDialogProps = {
    open: boolean;
    onOpenChange: (open: boolean) => void;
    item: FormHistory | null;
};

const eventBadgeVariant: Record<string, 'default' | 'secondary' | 'destructive' | 'outline'> = {
    created: 'default',
    updated: 'secondary',
    deleted: 'destructive',
};

const eventLabel: Record<string, string> = {
    created: 'Ditambahkan',
    updated: 'Diperbarui',
    deleted: 'Dihapus',
};

function renderValue(value: unknown): React.ReactNode {
    if (value === null || value === undefined) {
        return <span className="text-muted-foreground">-</span>;
    }

    if (typeof value === 'boolean') {
        return value ? 'Ya' : 'Tidak';
    }

    if (Array.isArray(value)) {
        if (value.length === 0) {
            return <span className="text-muted-foreground">-</span>;
        }

        return value.join(', ');
    }

    if (typeof value === 'object') {
        return JSON.stringify(value);
    }

    return String(value);
}

function flattenChanges(attributeChanges: Record<string, { old?: unknown; new?: unknown }>): { field: string; old?: unknown; new?: unknown }[] {
    const entries: { field: string; old?: unknown; new?: unknown }[] = [];

    for (const [key, change] of Object.entries(attributeChanges)) {
        entries.push({
            field: key,
            old: change.old,
            new: change.new,
        });
    }

    return entries;
}

export function AttributeChangesDialog({ open, onOpenChange, item }: AttributeChangesDialogProps) {
    if (!item) {
        return null;
    }

    const changes = item.attribute_changes;
    const hasChanges = changes && Object.keys(changes).length > 0;
    const flattened = hasChanges ? flattenChanges(changes) : [];

    return (
        <Dialog open={open} onOpenChange={onOpenChange}>
            <DialogContent className="max-w-3xl overflow-hidden">
                <DialogHeader>
                    <DialogTitle className="flex items-center gap-2">
                        <span>{item.description}</span>
                        <Badge variant={eventBadgeVariant[item.event] ?? 'outline'}>
                            {eventLabel[item.event] ?? item.event}
                        </Badge>
                    </DialogTitle>
                </DialogHeader>

                <div className="space-y-4 overflow-y-auto max-h-[calc(85vh-8rem)]">
                    <div className="text-sm text-muted-foreground space-y-1">
                        <div>Oleh: <span className="font-medium text-foreground">{item.causer?.full_name ?? item.causer?.username ?? '-'}</span></div>
                        <div>{item.formatted_created_at}</div>
                    </div>

                    {hasChanges && (
                        <div className="rounded-md border">
                            <div className="max-h-[300px] overflow-auto">
                                <Table>
                                    <TableHeader>
                                        <TableRow>
                                            <TableHead className="h-8 text-xs w-[30%]">Field</TableHead>
                                            <TableHead className="h-8 text-xs w-[35%]">Lama</TableHead>
                                            <TableHead className="h-8 text-xs w-[35%]">Baru</TableHead>
                                        </TableRow>
                                    </TableHeader>
                                    <TableBody>
                                        {flattened.map((row) => (
                                            <TableRow key={row.field}>
                                                <TableCell className="py-1.5 text-xs font-medium">
                                                    {row.field}
                                                </TableCell>
                                                <TableCell className="py-1.5 text-xs">
                                                    {row.old !== undefined ? (
                                                        <span className="text-red-600 dark:text-red-400">
                                                            {renderValue(row.old)}
                                                        </span>
                                                    ) : (
                                                        <span className="text-muted-foreground">-</span>
                                                    )}
                                                </TableCell>
                                                <TableCell className="py-1.5 text-xs">
                                                    {row.new !== undefined ? (
                                                        <span className="text-green-600 dark:text-green-400">
                                                            {renderValue(row.new)}
                                                        </span>
                                                    ) : (
                                                        <span className="text-muted-foreground">-</span>
                                                    )}
                                                </TableCell>
                                            </TableRow>
                                        ))}
                                    </TableBody>
                                </Table>
                            </div>
                        </div>
                    )}

                    {!hasChanges && (
                        <p className="text-sm text-muted-foreground text-center py-4">
                            Tidak ada perubahan data.
                        </p>
                    )}
                </div>
            </DialogContent>
        </Dialog>
    );
}
