/**
 * AiValidationResultsDialog Component
 *
 * Shows AI validation results with detailed token usage, summary, and change management.
 */

import { useMemo } from 'react';
import * as Diff from 'diff';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Check, X, Sparkles, AlertTriangle, Info, Cpu, Brain } from 'lucide-react';
import { Protected } from '@/components/auth/Protected';
import type { AiValidationResults, AiTokenUsage } from '../store/types';

interface AiValidationResultsDialogProps {
  results: AiValidationResults;
  revertedChanges: Set<string>;
  onRevert: (productIndex: number, fieldKey: string) => void;
  onAccept?: (productIndex: number, fieldKey: string) => void;
  onDismiss: () => void;
}

/**
 * Format token count for display
 */
const formatTokens = (value: number | null | undefined): string => {
  if (value === null || value === undefined) return '-';
  return value.toLocaleString();
};

/**
 * Convert a value to string for diff comparison
 */
const valueToString = (value: unknown): string => {
  if (value === null || value === undefined) return '';
  if (Array.isArray(value)) return value.join(', ');
  return String(value);
};

/**
 * Display a diff between two values with highlighting
 */
const DiffDisplay = ({ original, corrected }: { original: unknown; corrected: unknown }) => {
  const originalStr = valueToString(original) || '(empty)';
  const correctedStr = valueToString(corrected);

  // If values are identical, just show the value
  if (originalStr === correctedStr) {
    return <span className="text-sm">{correctedStr}</span>;
  }

  // Calculate word-level diff
  const diffResult = Diff.diffWords(originalStr, correctedStr);

  return (
    <span className="text-xs break-words">
      {diffResult.map((part, index) => {
        if (part.added) {
          return (
            <span
              key={index}
              className="bg-green-100 dark:bg-green-900/50 text-green-800 dark:text-green-200 rounded px-0.5"
            >
              {part.value}
            </span>
          );
        }
        if (part.removed) {
          return (
            <span
              key={index}
              className="bg-red-100 dark:bg-red-900/50 text-red-800 dark:text-red-200 line-through rounded px-0.5"
            >
              {part.value}
            </span>
          );
        }
        return <span key={index}>{part.value}</span>;
      })}
    </span>
  );
};

/**
 * Token Usage Display Component
 */
const TokenUsageDisplay = ({ tokenUsage }: { tokenUsage?: AiTokenUsage }) => {
  if (!tokenUsage) return null;

  const { prompt, completion, total, reasoning, cachedPrompt } = tokenUsage;

  // Check if we have any data to show
  const hasData = prompt !== null || completion !== null || total !== null;
  if (!hasData) return null;

  return (
    <div className="border rounded-lg p-3 bg-muted/30">
      <div className="text-xs font-medium text-muted-foreground mb-2 flex items-center gap-1">
        <Cpu className="h-3 w-3" />
        Token Usage
      </div>
      <div className="grid grid-cols-5 gap-2 text-center text-xs">
        <div>
          <div className="font-medium">{formatTokens(prompt)}</div>
          <div className="text-muted-foreground">Prompt</div>
        </div>
        <div>
          <div className="font-medium">{formatTokens(completion)}</div>
          <div className="text-muted-foreground">Completion</div>
        </div>
        <div>
          <div className="font-medium text-primary">{formatTokens(total)}</div>
          <div className="text-muted-foreground">Total</div>
        </div>
        <div>
          <div className="font-medium">{formatTokens(reasoning)}</div>
          <div className="text-muted-foreground">Reasoning</div>
        </div>
        <div>
          <div className="font-medium">{formatTokens(cachedPrompt)}</div>
          <div className="text-muted-foreground">Cached</div>
        </div>
      </div>
    </div>
  );
};

/**
 * Summary and Warnings Display Component
 */
const SummaryDisplay = ({
  summary,
  warnings,
  changesSummary,
}: {
  summary?: string;
  warnings?: string[];
  changesSummary?: string[];
}) => {
  if (!summary && (!warnings || warnings.length === 0) && (!changesSummary || changesSummary.length === 0)) {
    return null;
  }

  return (
    <div className="space-y-2">
      {/* Summary */}
      {summary && (
        <div className="p-3 rounded-lg bg-blue-50 dark:bg-blue-950/30 border border-blue-200 dark:border-blue-800">
          <div className="flex items-start gap-2">
            <Info className="h-4 w-4 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" />
            <div className="text-sm text-blue-800 dark:text-blue-200">{summary}</div>
          </div>
        </div>
      )}

      {/* Warnings */}
      {warnings && warnings.length > 0 && (
        <div className="p-3 rounded-lg bg-amber-50 dark:bg-amber-950/30 border border-amber-200 dark:border-amber-800">
          <div className="flex items-start gap-2">
            <AlertTriangle className="h-4 w-4 text-amber-600 dark:text-amber-400 mt-0.5 flex-shrink-0" />
            <div className="space-y-1">
              {warnings.map((warning, index) => (
                <div key={index} className="text-sm text-amber-800 dark:text-amber-200">
                  {warning}
                </div>
              ))}
            </div>
          </div>
        </div>
      )}

      {/* AI-generated change summaries */}
      {changesSummary && changesSummary.length > 0 && (
        <div className="p-3 rounded-lg bg-muted/50 border">
          <div className="text-xs font-medium text-muted-foreground mb-2">Changes Made</div>
          <ul className="list-disc list-inside space-y-1">
            {changesSummary.slice(0, 5).map((change, index) => (
              <li key={index} className="text-sm">{change}</li>
            ))}
            {changesSummary.length > 5 && (
              <li className="text-sm text-muted-foreground">
                ...and {changesSummary.length - 5} more
              </li>
            )}
          </ul>
        </div>
      )}
    </div>
  );
};

export const AiValidationResultsDialog = ({
  results,
  revertedChanges,
  onRevert,
  onAccept,
  onDismiss,
}: AiValidationResultsDialogProps) => {
  // Group changes by product
  const changesByProduct = useMemo(() => {
    const grouped = new Map<number, typeof results.changes>();
    results.changes.forEach((change) => {
      const existing = grouped.get(change.productIndex) || [];
      existing.push(change);
      grouped.set(change.productIndex, existing);
    });
    return grouped;
  }, [results.changes]);

  const activeChangesCount = results.changes.filter(
    (c) => !revertedChanges.has(`${c.productIndex}:${c.fieldKey}`)
  ).length;

  return (
    <Dialog open={true} onOpenChange={() => onDismiss()}>
      <DialogContent className="sm:max-w-2xl max-h-[85vh]">
        <DialogHeader>
          <DialogTitle className="flex items-center gap-2">
            <Sparkles className="h-5 w-5 text-primary" />
            AI Validation Complete
            {/* Model and reasoning effort badges - admin only */}
            <Protected permission="admin:debug">
              <div className="flex items-center gap-2 ml-auto">
                {results.model && (
                  <Badge variant="secondary" className="text-xs">
                    <Cpu className="h-3 w-3 mr-1" />
                    {results.model}
                  </Badge>
                )}
                {results.reasoningEffort && (
                  <Badge variant="outline" className="text-xs">
                    <Brain className="h-3 w-3 mr-1" />
                    {results.reasoningEffort}
                  </Badge>
                )}
              </div>
            </Protected>
          </DialogTitle>
        </DialogHeader>

        <div className="py-2 space-y-4">
          {/* Stats Summary */}
          <div className="flex items-center gap-4 p-4 bg-muted rounded-lg">
            <div className="text-center">
              <div className="text-2xl font-bold">{results.totalProducts}</div>
              <div className="text-xs text-muted-foreground">Products</div>
            </div>
            <div className="text-center">
              <div className="text-2xl font-bold text-primary">{results.productsWithChanges}</div>
              <div className="text-xs text-muted-foreground">With Changes</div>
            </div>
            <div className="text-center">
              <div className="text-2xl font-bold">{activeChangesCount}</div>
              <div className="text-xs text-muted-foreground">Active Changes</div>
            </div>
            <div className="text-center">
              <div className="text-2xl font-bold">{(results.processingTime / 1000).toFixed(1)}s</div>
              <div className="text-xs text-muted-foreground">Time</div>
            </div>
          </div>

          {/* Token Usage - Admin only */}
          <Protected permission="admin:debug">
            <TokenUsageDisplay tokenUsage={results.tokenUsage} />
          </Protected>

          {/* Summary, Warnings, and Change Summaries */}
          <SummaryDisplay
            summary={results.summary}
            warnings={results.warnings}
            changesSummary={results.changesSummary}
          />

          {/* Changes list */}
          {results.changes.length === 0 ? (
            <div className="text-center py-8 text-muted-foreground">
              <Check className="h-12 w-12 mx-auto mb-2 text-green-500" />
              <p>No corrections needed - all data looks good!</p>
            </div>
          ) : (
            <ScrollArea className="h-[250px]">
              <div className="space-y-4">
                {Array.from(changesByProduct.entries()).map(([productIndex, changes]) => (
                  <div key={productIndex} className="border rounded-lg p-3">
                    <div className="font-medium mb-2">Product {productIndex + 1}</div>
                    <div className="space-y-2">
                      {changes.map((change) => {
                        const isReverted = revertedChanges.has(
                          `${change.productIndex}:${change.fieldKey}`
                        );
                        return (
                          <div
                            key={`${change.productIndex}-${change.fieldKey}`}
                            className={`flex items-center justify-between p-2 rounded ${
                              isReverted ? 'bg-muted opacity-50' : 'bg-primary/5'
                            }`}
                          >
                            <div className="flex-1 min-w-0">
                              <div className="font-medium text-sm">{change.fieldKey}</div>
                              <div className="text-muted-foreground">
                                <DiffDisplay
                                  original={change.originalValue}
                                  corrected={change.correctedValue}
                                />
                              </div>
                            </div>
                            {/* Accept/Reject toggle buttons */}
                            <div className="flex items-center gap-1 flex-shrink-0 ml-2">
                              <Button
                                variant={isReverted ? 'outline' : 'default'}
                                size="sm"
                                className={`h-7 px-2 ${!isReverted ? 'bg-green-600 hover:bg-green-700 text-white' : ''}`}
                                onClick={() => {
                                  if (isReverted && onAccept) {
                                    onAccept(change.productIndex, change.fieldKey);
                                  }
                                }}
                                disabled={!isReverted}
                                title="Accept this change"
                              >
                                <Check className="h-3.5 w-3.5" />
                              </Button>
                              <Button
                                variant={isReverted ? 'destructive' : 'outline'}
                                size="sm"
                                className="h-7 px-2"
                                onClick={() => {
                                  if (!isReverted) {
                                    onRevert(change.productIndex, change.fieldKey);
                                  }
                                }}
                                disabled={isReverted}
                                title="Reject this change"
                              >
                                <X className="h-3.5 w-3.5" />
                              </Button>
                            </div>
                          </div>
                        );
                      })}
                    </div>
                  </div>
                ))}
              </div>
            </ScrollArea>
          )}
        </div>

        <DialogFooter>
          <Button onClick={onDismiss}>Done</Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
};
