import { useEffect, useState } from 'react';
import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
import { ArrowRight, Plus, Minus, Edit } from 'lucide-react';
import { useEntityVersions } from '@/hooks/useEntityVersions';
import type { EntityType } from '@/types/versioning';

interface VersionComparisonDialogProps {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  entityType: EntityType;
  entityId: string;
  fromVersionId: string;
  toVersionId: string;
}

interface VersionDiff {
  [fieldName: string]: {
    from: unknown;
    to: unknown;
  };
}

export function VersionComparisonDialog({
  open,
  onOpenChange,
  entityType,
  entityId,
  fromVersionId,
  toVersionId,
}: VersionComparisonDialogProps) {
  const { versions, compareVersions } = useEntityVersions(entityType, entityId);
  const [diff, setDiff] = useState<VersionDiff | null>(null);
  const [loading, setLoading] = useState(true);

  const fromVersion = versions.find(v => v.version_id === fromVersionId);
  const toVersion = versions.find(v => v.version_id === toVersionId);

  useEffect(() => {
    const loadDiff = async () => {
      if (open && fromVersionId && toVersionId) {
        setLoading(true);
        const result = await compareVersions(fromVersionId, toVersionId);
        setDiff(result as VersionDiff);
        setLoading(false);
      }
    };

    loadDiff();
  }, [open, fromVersionId, toVersionId, compareVersions]);

  const formatValue = (value: any): string => {
    if (value === null || value === undefined) return 'null';
    if (typeof value === 'boolean') return value ? 'true' : 'false';
    if (typeof value === 'object') return JSON.stringify(value, null, 2);
    return String(value);
  };

  const formatFieldName = (fieldName: string): string => {
    return fieldName
      .split('_')
      .map(word => word.charAt(0).toUpperCase() + word.slice(1))
      .join(' ');
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-4xl max-h-[80vh] overflow-y-auto">
        <DialogHeader>
          <DialogTitle>Compare Versions</DialogTitle>
          <div className="flex items-center gap-4 text-sm text-muted-foreground mt-2">
            <div className="flex items-center gap-2">
              <Badge variant="outline">Version {fromVersion?.version_number}</Badge>
              <span>{new Date(fromVersion?.created_at || '').toLocaleString()}</span>
            </div>
            <ArrowRight className="h-4 w-4" />
            <div className="flex items-center gap-2">
              <Badge variant="outline">Version {toVersion?.version_number}</Badge>
              <span>{new Date(toVersion?.created_at || '').toLocaleString()}</span>
            </div>
          </div>
        </DialogHeader>

        <ScrollArea className="h-[500px] pr-4">
          {loading ? (
            <div className="flex items-center justify-center py-8">
              <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary" />
            </div>
          ) : diff && Object.keys(diff).length > 0 ? (
            <div className="space-y-4">
              {Object.entries(diff).map(([fieldName, changes]: [string, any]) => {
                const isAdded = changes.from === null;
                const isRemoved = changes.to === null;
                const isModified = changes.from !== null && changes.to !== null;

                return (
                  <div key={fieldName} className="border rounded-lg p-4 space-y-2">
                    <div className="flex items-center gap-2">
                      {isAdded && <Plus className="h-4 w-4 text-green-500" />}
                      {isRemoved && <Minus className="h-4 w-4 text-red-500" />}
                      {isModified && <Edit className="h-4 w-4 text-blue-500" />}
                      <span className="font-medium">{formatFieldName(fieldName)}</span>
                      <Badge
                        variant="outline"
                        className={
                          isAdded
                            ? 'bg-green-500/10 text-green-700 dark:text-green-400'
                            : isRemoved
                            ? 'bg-red-500/10 text-red-700 dark:text-red-400'
                            : 'bg-blue-500/10 text-blue-700 dark:text-blue-400'
                        }
                      >
                        {isAdded ? 'Added' : isRemoved ? 'Removed' : 'Modified'}
                      </Badge>
                    </div>

                    <Separator />

                    <div className="grid grid-cols-2 gap-4">
                      {/* From value */}
                      <div className="space-y-1">
                        <div className="text-xs text-muted-foreground font-medium">Before</div>
                        <div
                          className={`p-3 rounded-md font-mono text-xs whitespace-pre-wrap ${
                            isRemoved
                              ? 'bg-red-500/10 text-red-700 dark:text-red-400 line-through'
                              : 'bg-muted'
                          }`}
                        >
                          {formatValue(changes.from)}
                        </div>
                      </div>

                      {/* To value */}
                      <div className="space-y-1">
                        <div className="text-xs text-muted-foreground font-medium">After</div>
                        <div
                          className={`p-3 rounded-md font-mono text-xs whitespace-pre-wrap ${
                            isAdded
                              ? 'bg-green-500/10 text-green-700 dark:text-green-400 font-semibold'
                              : isModified
                              ? 'bg-blue-500/10 text-blue-700 dark:text-blue-400 font-semibold'
                              : 'bg-muted'
                          }`}
                        >
                          {formatValue(changes.to)}
                        </div>
                      </div>
                    </div>
                  </div>
                );
              })}
            </div>
          ) : (
            <div className="text-center py-8 text-muted-foreground">
              <p>No differences found between these versions</p>
            </div>
          )}
        </ScrollArea>
      </DialogContent>
    </Dialog>
  );
}
