'use client';

import * as React from 'react';
import { Download, CheckCircle, XCircle, Loader2, Clock, TrendingUp, RefreshCw } from 'lucide-react';
import { cn } from '@/lib/utils/cn';
import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Progress } from '@/components/ui/progress';
import { downloadBlob, formatFileSize, generateOutputFilename } from '@/lib/media/utils/fileUtils';
import type { ConversionJob } from '@/types/media';

export interface ConversionPreviewProps {
  job: ConversionJob;
  onDownload?: () => void;
  onRetry?: () => void;
}

export function ConversionPreview({ job, onDownload, onRetry }: ConversionPreviewProps) {
  const [previewUrl, setPreviewUrl] = React.useState<string | null>(null);
  const [elapsedTime, setElapsedTime] = React.useState(0);
  const [estimatedTimeRemaining, setEstimatedTimeRemaining] = React.useState<number | null>(null);

  // Timer for elapsed time and estimation
  React.useEffect(() => {
    if (job.status === 'processing' || job.status === 'loading') {
      const interval = setInterval(() => {
        if (job.startTime) {
          const elapsed = Date.now() - job.startTime;
          setElapsedTime(elapsed);

          // Estimate time remaining based on progress
          if (job.progress > 5 && job.progress < 100) {
            const progressRate = job.progress / elapsed;
            const remainingProgress = 100 - job.progress;
            const estimated = remainingProgress / progressRate;
            setEstimatedTimeRemaining(estimated);
          }
        }
      }, 100);

      return () => clearInterval(interval);
    } else {
      setEstimatedTimeRemaining(null);
    }
  }, [job.status, job.startTime, job.progress]);

  // Create preview URL for result
  React.useEffect(() => {
    if (job.result && job.status === 'completed') {
      console.log('[Preview] Creating object URL for blob');
      const url = URL.createObjectURL(job.result);
      setPreviewUrl(url);
      console.log('[Preview] Object URL created:', url);

      return () => {
        console.log('[Preview] Revoking object URL:', url);
        URL.revokeObjectURL(url);
      };
    } else {
      setPreviewUrl(null);
    }
  }, [job.result, job.status]);

  const handleDownload = () => {
    if (job.result) {
      const filename = generateOutputFilename(job.inputFile.name, job.outputFormat.extension);
      downloadBlob(job.result, filename);
      onDownload?.();
    }
  };

  const renderPreview = () => {
    if (!previewUrl || !job.result) return null;

    const category = job.outputFormat.category;

    // Log blob details for debugging
    console.log('[Preview] Blob details:', {
      size: job.result.size,
      type: job.result.type,
      previewUrl,
      outputFormat: job.outputFormat.extension,
    });

    switch (category) {
      case 'image':
        return (
          <div className="mt-3 rounded-lg overflow-hidden bg-muted/30 flex items-center justify-center p-4">
            <img
              src={previewUrl}
              alt="Converted image preview"
              className="max-w-full max-h-64 object-contain"
              onError={(e) => {
                console.error('[Preview] Image failed to load:', {
                  src: previewUrl,
                  blobSize: job.result?.size,
                  blobType: job.result?.type,
                  error: e,
                });
              }}
              onLoad={() => {
                console.log('[Preview] Image loaded successfully');
              }}
            />
          </div>
        );

      case 'video':
        return (
          <div className="mt-3 rounded-lg overflow-hidden bg-muted/30">
            <video src={previewUrl} controls className="w-full max-h-64">
              Your browser does not support video playback.
            </video>
          </div>
        );

      case 'audio':
        return (
          <div className="mt-4 rounded-lg overflow-hidden bg-muted/30 p-4">
            <audio src={previewUrl} controls className="w-full">
              Your browser does not support audio playback.
            </audio>
          </div>
        );

      default:
        return null;
    }
  };

  const formatTime = (ms: number) => {
    const seconds = Math.floor(ms / 1000);
    if (seconds < 60) return `${seconds}s`;
    const minutes = Math.floor(seconds / 60);
    const remainingSeconds = seconds % 60;
    return `${minutes}m ${remainingSeconds}s`;
  };

  const renderStatus = () => {
    switch (job.status) {
      case 'loading':
        return (
          <div className="space-y-2">
            <div className="flex items-center gap-2 text-muted-foreground">
              <Loader2 className="h-3.5 w-3.5 animate-spin text-primary" />
              <span className="text-xs font-medium">Loading converter...</span>
            </div>
            <div className="flex items-center gap-1.5 text-[10px] text-muted-foreground">
              <Clock className="h-3 w-3" />
              <span>{formatTime(elapsedTime)}</span>
            </div>
          </div>
        );

      case 'processing':
        return (
          <div className="space-y-2">
            <div className="flex items-center justify-between">
              <div className="flex items-center gap-2 text-muted-foreground">
                <Loader2 className="h-3.5 w-3.5 animate-spin text-primary" />
                <span className="text-xs font-medium">Converting...</span>
              </div>
              <span className="text-[10px] text-muted-foreground tabular-nums">{job.progress}%</span>
            </div>
            <Progress value={job.progress} className="h-1" />
            <div className="flex items-center gap-3 text-[10px] text-muted-foreground">
              <div className="flex items-center gap-1.5">
                <Clock className="h-3 w-3" />
                <span>{formatTime(elapsedTime)}</span>
              </div>
              {estimatedTimeRemaining && (
                <div className="flex items-center gap-1.5">
                  <TrendingUp className="h-3 w-3" />
                  <span>~{formatTime(estimatedTimeRemaining)} left</span>
                </div>
              )}
            </div>
          </div>
        );

      case 'completed':
        const inputSize = job.inputFile.size;
        const outputSize = job.result?.size || 0;
        const sizeReduction = inputSize > 0 ? ((inputSize - outputSize) / inputSize) * 100 : 0;

        return (
          <div className="space-y-2">
            <div className="flex items-center gap-2">
              <CheckCircle className="h-3.5 w-3.5 text-primary" />
              <span className="text-xs font-medium">Complete</span>
            </div>

            <div className="bg-muted/50 rounded-lg p-2.5 space-y-1">
              <div className="flex items-center justify-between text-xs">
                <span className="text-muted-foreground">Input</span>
                <span className="font-medium tabular-nums">{formatFileSize(inputSize)}</span>
              </div>
              <div className="flex items-center justify-between text-xs">
                <span className="text-muted-foreground">Output</span>
                <div className="flex items-center gap-1.5">
                  <span className="font-medium tabular-nums">{formatFileSize(outputSize)}</span>
                  {Math.abs(sizeReduction) > 1 && (
                    <span className={cn(
                      "text-[10px] px-1.5 py-0.5 rounded-full",
                      sizeReduction > 0
                        ? "bg-primary/10 text-primary"
                        : "bg-muted text-muted-foreground"
                    )}>
                      {sizeReduction > 0 ? '-' : '+'}{Math.abs(sizeReduction).toFixed(0)}%
                    </span>
                  )}
                </div>
              </div>
            </div>
          </div>
        );

      case 'error':
        return (
          <div className="flex items-center gap-2 text-destructive">
            <XCircle className="h-3.5 w-3.5" />
            <span className="text-xs font-medium">Conversion failed</span>
          </div>
        );

      default:
        return null;
    }
  };

  if (job.status === 'pending') {
    return null;
  }

  return (
    <Card className="animate-fade-in">
      <CardHeader>
        <CardTitle className="text-sm">Conversion</CardTitle>
      </CardHeader>
      <CardContent>
        <div className="space-y-3">
          {renderStatus()}

          {job.error && (
            <div className="bg-destructive/10 border border-destructive/20 rounded-md p-2.5">
              <p className="text-xs text-destructive">{job.error}</p>
            </div>
          )}

          {job.status === 'error' && onRetry && (
            <Button onClick={onRetry} variant="outline" className="w-full">
              <RefreshCw className="h-3.5 w-3.5 mr-1.5" />
              Retry
            </Button>
          )}

          {job.status === 'completed' && renderPreview()}

          {job.status === 'completed' && job.result && (
            <Button onClick={handleDownload} className="w-full">
              <Download className="h-3.5 w-3.5 shrink-0 mr-1.5" />
              <span className="truncate min-w-0">
                {generateOutputFilename(job.inputFile.name, job.outputFormat.extension)}
              </span>
            </Button>
          )}

          {job.status === 'completed' && job.startTime && job.endTime && (
            <p className="text-[10px] text-muted-foreground text-center">
              {((job.endTime - job.startTime) / 1000).toFixed(1)}s
            </p>
          )}
        </div>
      </CardContent>
    </Card>
  );
}
