import React from 'react';
import { useParams } from 'react-router-dom';
import { formatDistanceToNow } from 'date-fns';
import { useJob, useJobDownloads } from '../hooks/useJob';
import { getLanguageLabel } from '../utils/language';

const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));

// Shared download function
const handleDownload = async (url: string, filename: string) => {
  try {
    // Fetch the file as a blob to force download
    const response = await fetch(url);
    if (!response.ok) throw new Error('Failed to fetch file');
    
    const blob = await response.blob();
    const blobUrl = URL.createObjectURL(blob);
    
    const link = document.createElement('a');
    link.href = blobUrl;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    
    // Clean up the blob URL
    URL.revokeObjectURL(blobUrl);
  } catch (error) {
    console.error('Download failed:', error);
    // Fallback to direct link if fetch fails
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  }
};

const DownloadCard = ({ 
  language, 
  files, 
  jobTitle 
}: { 
  language: string; 
  files: Record<string, string>;
  jobTitle: string;
}) => {
  const languageName = getLanguageLabel(language);

  const formatFilename = (type: string) => {
    const sanitizedTitle = jobTitle.replace(/[^a-zA-Z0-9\-_]/g, '_');
    const extensions: Record<string, string> = {
      'captions_vtt': 'captions.vtt',
      'audio_description_vtt': 'audio_descriptions.vtt',
      'audio_description_mp3': 'audio_descriptions.mp3',
      'accessible_video_mp4': 'accessible_video.mp4',
      'accessible_captions_vtt': 'accessible_captions.vtt',
      'sdh_captions_vtt': 'sdh_captions.vtt',
      'descriptive_transcript': 'descriptive_transcript.txt'
    };
    return `${sanitizedTitle}_${language}_${extensions[type] || type}`;
  };

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-6">
      <h3 className="text-lg font-medium text-gray-900 mb-4">{languageName}</h3>
      
      <div className="space-y-3">
        {Object.entries(files).map(([type, url]) => {
          const typeLabels: Record<string, string> = {
            'captions_vtt': 'Captions (VTT)',
            'audio_description_vtt': 'Audio Descriptions (VTT)',
            'audio_description_mp3': 'Audio Descriptions (MP3)',
            'accessible_video_mp4': 'Accessible Video (MP4)',
            'accessible_captions_vtt': 'Re-timed Captions (VTT)',
            'sdh_captions_vtt': 'SDH Captions (VTT)',
            'descriptive_transcript': 'Descriptive Transcript (TXT)'
          };

          return (
            <div key={type} className="flex items-center justify-between">
              <div>
                <p className="text-sm font-medium text-gray-900">
                  {typeLabels[type] || type}
                </p>
                <p className="text-xs text-gray-500">
                  {formatFilename(type)}
                </p>
              </div>
              <button
                onClick={async () => await handleDownload(url, formatFilename(type))}
                className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
              >
                <svg className="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                </svg>
                Download
              </button>
            </div>
          );
        })}
      </div>
    </div>
  );
};

export function Downloads() {
  const { id } = useParams();

  const { data: job, isLoading: jobLoading } = useJob(id!);
  const { data: downloads, isLoading: downloadsLoading, error: downloadsError } = useJobDownloads(
    id!,
    job?.status,
  );

  const [downloadingAll, setDownloadingAll] = React.useState(false);

  const handleDownloadAll = async () => {
    if (!downloads?.downloads || !job) return;
    setDownloadingAll(true);
    try {
      const sanitizedTitle = job.title.replace(/[^a-zA-Z0-9\-_]/g, '_');
      const tasks: Array<{ url: string; filename: string }> = [];

      if (typeof downloads.downloads.source_video === 'string') {
        const srcName = (job.source?.original_filename || job.title || 'video').replace(/[^a-zA-Z0-9\-_]/g, '_');
        tasks.push({ url: downloads.downloads.source_video, filename: `${srcName}_source.mp4` });
      }

      const extensions: Record<string, string> = {
        captions_vtt: 'captions.vtt',
        audio_description_vtt: 'audio_descriptions.vtt',
        audio_description_mp3: 'audio_descriptions.mp3',
        accessible_video_mp4: 'accessible_video.mp4',
        accessible_captions_vtt: 'accessible_captions.vtt',
        sdh_captions_vtt: 'sdh_captions.vtt',
        descriptive_transcript: 'descriptive_transcript.txt',
      };

      for (const [lang, files] of Object.entries(downloads.downloads)) {
        if (lang === 'source_video' || typeof files !== 'object') continue;
        for (const [type, url] of Object.entries(files as Record<string, string>)) {
          const ext = extensions[type] || type;
          tasks.push({ url, filename: `${sanitizedTitle}_${lang}_${ext}` });
        }
      }

      for (const task of tasks) {
        await handleDownload(task.url, task.filename);
        await sleep(400);
      }
    } finally {
      setDownloadingAll(false);
    }
  };

  if (jobLoading) {
    return (
      <div className="container mx-auto px-4 py-8">
        <div className="animate-pulse">
          <div className="h-8 bg-gray-200 rounded w-1/3 mb-8"></div>
          <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
            {[...Array(3)].map((_, i) => (
              <div key={i} className="h-48 bg-gray-200 rounded"></div>
            ))}
          </div>
        </div>
      </div>
    );
  }

  if (!job) {
    return (
      <div className="container mx-auto px-4 py-8">
        <div className="bg-red-50 border border-red-200 rounded-md p-4">
          <p className="text-red-800">Job not found</p>
        </div>
      </div>
    );
  }

  if (job.status !== 'completed') {
    return (
      <div className="container mx-auto px-4 py-8">
        <div className="bg-yellow-50 border border-yellow-200 rounded-md p-4">
          <h2 className="text-lg font-medium text-yellow-800 mb-2">Job Not Ready</h2>
          <p className="text-yellow-700">
            This job is still being processed. Downloads will be available once the job is completed.
          </p>
          <p className="text-sm text-yellow-600 mt-2">
            Current status: {job.status.replace(/_/g, ' ').toUpperCase()}
          </p>
        </div>
      </div>
    );
  }

  if (downloadsError) {
    return (
      <div className="container mx-auto px-4 py-8">
        <div className="bg-red-50 border border-red-200 rounded-md p-4">
          <p className="text-red-800">Failed to load download links</p>
        </div>
      </div>
    );
  }

  if (downloadsLoading) {
    return (
      <div className="container mx-auto px-4 py-8">
        <h1 className="text-3xl font-bold text-gray-900 mb-8">
          Downloads: {job.source?.original_filename || job.title}
        </h1>
        <div className="animate-pulse grid gap-6 md:grid-cols-2 lg:grid-cols-3">
          {[...Array(3)].map((_, i) => (
            <div key={i} className="h-48 bg-gray-200 rounded"></div>
          ))}
        </div>
      </div>
    );
  }

  return (
    <div className="container mx-auto px-4 py-8">
      <div className="mb-8">
        <div className="flex items-start justify-between">
          <div>
            <h1 className="text-3xl font-bold text-gray-900 mb-2">
              Downloads: {job.source?.original_filename || job.title}
            </h1>
            <div className="flex items-center space-x-4 text-sm text-gray-600">
              <span>Completed {formatDistanceToNow(new Date(job.updated_at))} ago</span>
              <span>{Object.entries(downloads?.downloads || {}).filter(([key, value]) => key !== 'source_video' && typeof value === 'object').length} languages available</span>
            </div>
          </div>
          {downloads?.downloads && Object.keys(downloads.downloads).length > 0 && (
            <button
              onClick={handleDownloadAll}
              disabled={downloadingAll}
              className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 disabled:opacity-50 disabled:cursor-not-allowed"
            >
              <svg className="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4" />
              </svg>
              {downloadingAll ? 'Downloading...' : 'Download All'}
            </button>
          )}
        </div>
      </div>

      {!downloads?.downloads || Object.keys(downloads.downloads).length === 0 ? (
        <div className="bg-gray-50 border border-gray-200 rounded-md p-8 text-center">
          <p className="text-gray-600">No download files available</p>
        </div>
      ) : (
        <div className="space-y-8">
          {/* Source Video Section */}
          {typeof downloads.downloads.source_video === 'string' && (
            <div className="bg-white border border-gray-200 rounded-lg p-6">
              <h3 className="text-lg font-medium text-gray-900 mb-4">SOURCE_VIDEO</h3>
              <div className="flex items-center justify-between">
                <div>
                  <p className="text-sm font-medium text-gray-900">
                    {job.source?.original_filename || 'source.mp4'}
                  </p>
                  <p className="text-xs text-gray-500">
                    {(job.source?.original_filename || job.title || 'video').replace(/[^a-zA-Z0-9\-_]/g, '_')}_source.mp4
                  </p>
                </div>
                <button
                  onClick={async () => {
                    const filename = (job.source?.original_filename || job.title || 'video').replace(/[^a-zA-Z0-9\-_]/g, '_') + '_source.mp4';
                    await handleDownload(downloads.downloads.source_video as string, filename);
                  }}
                  className="inline-flex items-center px-3 py-1 border border-transparent text-sm font-medium rounded-md text-indigo-700 bg-indigo-100 hover:bg-indigo-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                >
                  <svg className="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 10v6m0 0l-3-3m3 3l3-3m2 8H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                  </svg>
                  Download
                </button>
              </div>
            </div>
          )}
          
          {/* Language Downloads */}
          <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
            {Object.entries(downloads.downloads)
              .filter(([key, value]) => key !== 'source_video' && typeof value === 'object')
              .map(([language, files]) => (
                <DownloadCard
                  key={language}
                  language={language}
                  files={files as Record<string, string>}
                  jobTitle={job.title}
                />
              ))}
          </div>
        </div>
      )}

      <div className="mt-8 bg-blue-50 border border-blue-200 rounded-md p-4">
        <h3 className="text-sm font-medium text-blue-800 mb-2">Download Information</h3>
        <ul className="text-xs text-blue-700 space-y-1">
          <li>• Download links are valid for 24 hours</li>
          <li>• VTT files can be used with any video player that supports WebVTT</li>
          <li>• MP3 files contain synchronized audio descriptions for accessibility</li>
          <li>• Accessible Video (MP4) contains the source video with pauses inserted for audio descriptions</li>
          <li>• Re-timed Captions (VTT) are synced to the accessible video timing</li>
          <li>• Contact support if you need help integrating these files</li>
        </ul>
      </div>
    </div>
  );
}