import { useState } from 'react';
import { useParams, Link } from 'react-router-dom';
import { formatDistanceToNow } from 'date-fns';
import { useCancelJob, useJob, useJobDownloads, useJobVttContent, useRetryJob, useReturnToQC, useUpdateJob } from '../../hooks/useJob';
import { useAuthStore } from '../../lib/auth';
import type { JobFailure } from '../../types/api';
import { StatusBadge } from '../../components/StatusBadge';
import { VideoWithCaptions } from '../../components/VideoWithCaptions';
import { useGlobalWebSocket } from '../../contexts/GlobalWebSocketContext';
import { useToastContext } from '../../contexts/ToastContext';
import { VersionsTab } from './VersionsTab';

const RETURN_TO_QC_ELIGIBLE_STATUSES = [
  'completed', 'pending_final_review', 'rejected', 'qc_feedback',
  'tts_failed', 'render_failed', 'approved_english', 'approved_source',
];

const CANCELLABLE_STATUSES = new Set([
  'ingesting', 'ai_processing', 'translating', 'tts_generating', 'rendering_video', 'rendering_qc',
]);


const FAILURE_STEP_TO_PIPELINE: Record<string, string> = {
  ingestion: 'ingesting',
  ai_processing: 'ai_processing',
  translation: 'translating',
  tts: 'tts_generating',
  render: 'rendering_video',
};

const ProgressIndicator = ({ status, failure }: { status: string; failure?: JobFailure }) => {
  // New flow: processing happens before QC, approval goes directly to final review
  const steps = [
    'created',
    'ingesting',
    'ai_processing',
    'translating',
    'tts_generating',
    'rendering_video',
    'pending_qc',
    'pending_final_review',
    'completed'
  ];

  // Handle legacy approved_english/approved_source statuses (map to pending_final_review)
  const normalizedStatus = (status === 'approved_english' || status === 'approved_source')
    ? 'pending_final_review'
    : status;
  const currentIndex = steps.indexOf(normalizedStatus);
  const isRejected = status === 'rejected';
  const isCancelled = status === 'cancelled';
  const isFailed = status === 'tts_failed' || status === 'render_failed' || status === 'processing_failed';

  // For failed states, find which step they failed at
  const failedAtStep = status === 'tts_failed' ? 'tts_generating' :
                       status === 'render_failed' ? 'rendering_video' :
                       status === 'processing_failed' && failure?.step
                         ? FAILURE_STEP_TO_PIPELINE[failure.step] ?? null
                         : null;
  const failedAtIndex = failedAtStep ? steps.indexOf(failedAtStep) : -1;

  if (isRejected) {
    return (
      <div className="bg-red-50 border border-red-200 rounded-md p-4">
        <p className="text-red-800 font-medium">Job Rejected</p>
        <p className="text-red-600 text-sm mt-1">
          This job has been rejected during review. Please check the review notes for feedback.
        </p>
      </div>
    );
  }

  if (isCancelled) {
    return (
      <div className="bg-gray-50 border border-gray-300 rounded-md p-4">
        <p className="text-gray-700 font-medium">Job Cancelled</p>
        <p className="text-gray-500 text-sm mt-1">
          This job was stopped before completion. You can retry it from the failed state.
        </p>
      </div>
    );
  }

  if (isFailed) {
    const failedStepLabel = failedAtStep?.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase());
    return (
      <div className="bg-white border border-gray-200 rounded-lg p-4">
        <h3 className="text-sm font-medium text-gray-900 mb-3">Processing Progress</h3>
        <div className="space-y-2">
          {steps.map((step, index) => (
            <div key={step} className="flex items-center">
              <div className={`w-3 h-3 rounded-full mr-3 ${
                index < failedAtIndex ? 'bg-green-500' :
                index === failedAtIndex ? 'bg-red-500' : 'bg-gray-300'
              }`} />
              <span className={`text-sm ${
                index === failedAtIndex ? 'font-medium text-red-600' :
                index < failedAtIndex ? 'text-gray-600' : 'text-gray-400'
              }`}>
                {step.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
                {index === failedAtIndex && ' (Failed)'}
              </span>
            </div>
          ))}
        </div>
        <div className="mt-3 pt-3 border-t border-gray-200 space-y-1">
          <p className="text-xs text-red-600 font-medium">
            {failedStepLabel ? `Failed at: ${failedStepLabel}` : 'Processing failed'}
          </p>
          {failure?.message && (
            <p className="text-xs text-red-500 break-words">{failure.message}</p>
          )}
        </div>
      </div>
    );
  }

  return (
    <div className="bg-white border border-gray-200 rounded-lg p-4">
      <h3 className="text-sm font-medium text-gray-900 mb-3">Processing Progress</h3>
      <div className="space-y-2">
        {steps.map((step, index) => (
          <div key={step} className="flex items-center">
            <div className={`w-3 h-3 rounded-full mr-3 ${
              index <= currentIndex ? 'bg-green-500' : 'bg-gray-300'
            }`} />
            <span className={`text-sm ${
              index === currentIndex ? 'font-medium text-gray-900' :
              index < currentIndex ? 'text-gray-600' : 'text-gray-400'
            }`}>
              {step.replace(/_/g, ' ').replace(/\b\w/g, l => l.toUpperCase())}
            </span>
          </div>
        ))}
      </div>
    </div>
  );
};

export function JobDetail() {
  const { id } = useParams();
  const [activeTab, setActiveTab] = useState<'overview' | 'video' | 'assets' | 'history' | 'versions'>('overview');

  const { data: job, isLoading, error } = useJob(id!);
  const { data: downloads } = useJobDownloads(id!, job?.status);
  // Get source language from job (default to 'en' for backwards compatibility)
  const sourceLanguage = job?.source?.language || 'en';
  const { data: sourceVtt } = useJobVttContent(id!, sourceLanguage);

  // Get connection status from global WebSocket
  const { connectionStatus } = useGlobalWebSocket();

  // Retry / cancel mutations
  const retryJobMutation = useRetryJob();
  const cancelJobMutation = useCancelJob();
  const updateJobMutation = useUpdateJob();
  const toast = useToastContext();
  const [showCancelConfirm, setShowCancelConfirm] = useState(false);
  const [editingTitle, setEditingTitle] = useState(false);
  const [titleDraft, setTitleDraft] = useState('');

  // Return to QC
  const { user } = useAuthStore();
  const returnToQCMutation = useReturnToQC();
  const [showReturnToQC, setShowReturnToQC] = useState(false);
  const [returnToQCNotes, setReturnToQCNotes] = useState('');

  const canReturnToQC = user &&
    (user.role === 'production' || user.role === 'admin') &&
    job?.status && RETURN_TO_QC_ELIGIBLE_STATUSES.includes(job.status);

  const canEditTitle = user && ['admin', 'production', 'project_manager'].includes(user.role || '');

  const handleTitleSave = async () => {
    if (!id || !titleDraft.trim() || titleDraft.trim() === job?.title) { setEditingTitle(false); return; }
    try {
      await updateJobMutation.mutateAsync({ id, data: { title: titleDraft.trim() } as never });
      toast.toastOnly.success('Renamed');
    } catch {
      toast.toastOnly.error('Failed to rename');
    } finally {
      setEditingTitle(false);
    }
  };

  const handleReturnToQC = async () => {
    if (!id || !returnToQCNotes.trim()) return;
    try {
      await returnToQCMutation.mutateAsync({ id, notes: returnToQCNotes.trim() });
      toast.toastOnly.success('Job returned to QC review');
      setShowReturnToQC(false);
      setReturnToQCNotes('');
    } catch {
      toast.toastOnly.error('Failed to return job to QC');
    }
  };


  const handleRetryJob = async () => {
    if (!id) return;
    try {
      await retryJobMutation.mutateAsync({ id });
      toast.toastOnly.success('Retry initiated');
    } catch {
      toast.toastOnly.error('Failed to retry job');
    }
  };

  const isFailedStatus = job?.status === 'tts_failed' || job?.status === 'render_failed' || job?.status === 'processing_failed';
  const canCancel = user && ['admin', 'production'].includes(user.role || '') && job?.status && CANCELLABLE_STATUSES.has(job.status);

  const handleCancelJob = async () => {
    if (!id) return;
    try {
      await cancelJobMutation.mutateAsync({ id });
      toast.toastOnly.success('Job cancelled');
      setShowCancelConfirm(false);
    } catch {
      toast.toastOnly.error('Failed to cancel job');
    }
  };


  // Get video URL from downloads
  const videoUrl = typeof downloads?.downloads?.source_video === 'string'
    ? downloads.downloads.source_video
    : '';

  const tabs = [
    { id: 'overview' as const, label: 'Overview', icon: '📋', disabled: false },
    { id: 'video' as const, label: 'Video Preview', icon: '🎥', disabled: !videoUrl },
    { id: 'assets' as const, label: 'Assets', icon: '📁', disabled: false },
    { id: 'history' as const, label: 'History', icon: '📜', disabled: false },
    { id: 'versions' as const, label: 'VTT Versions', icon: '🕒', disabled: false },
  ];

  if (isLoading) {
    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 lg:grid-cols-3">
            <div className="lg:col-span-2 space-y-6">
              <div className="h-64 bg-gray-200 rounded"></div>
              <div className="h-32 bg-gray-200 rounded"></div>
            </div>
            <div className="h-48 bg-gray-200 rounded"></div>
          </div>
        </div>
      </div>
    );
  }

  if (error || !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">Failed to load job details</p>
        </div>
      </div>
    );
  }

  const renderTabContent = () => {
    switch (activeTab) {
      case 'overview':
        return (
          <div className="space-y-6">
            {/* Job Information */}
            <div className="bg-white border border-gray-200 rounded-lg p-6">
              <h2 className="text-lg font-medium text-gray-900 mb-4">Job Information</h2>
              <dl className="grid grid-cols-1 gap-x-4 gap-y-4 sm:grid-cols-2">
                <div>
                  <dt className="text-sm font-medium text-gray-500">Original File</dt>
                  <dd className="text-sm text-gray-900 mt-1">{job.source?.original_filename || 'N/A'}</dd>
                </div>
                <div>
                  <dt className="text-sm font-medium text-gray-500">Source Language</dt>
                  <dd className="text-sm text-gray-900 mt-1">{job.source?.language?.toUpperCase() || 'N/A'}</dd>
                </div>
                <div>
                  <dt className="text-sm font-medium text-gray-500">Requested Languages</dt>
                  <dd className="text-sm text-gray-900 mt-1">
                    {job.requested_outputs?.languages?.join(', ') || 'N/A'}
                  </dd>
                </div>
                <div>
                  <dt className="text-sm font-medium text-gray-500">Outputs</dt>
                  <dd className="text-sm text-gray-900 mt-1">
                    <div className="space-y-1">
                      {job.requested_outputs?.captions_vtt && <div>✓ Captions (VTT)</div>}
                      {job.requested_outputs?.audio_description_vtt && <div>✓ Audio Descriptions (VTT)</div>}
                      {job.requested_outputs?.audio_description_mp3 && <div>✓ Audio Descriptions (MP3)</div>}
                      {job.requested_outputs?.accessible_video_mp4 && <div>✓ Accessible Video (MP4)</div>}
                      {job.requested_outputs?.sdh_vtt && <div>✓ SDH Captions (VTT)</div>}
                    </div>
                  </dd>
                </div>
                {/* Transcreation Languages - HIDDEN: Not fully implemented */}
                {/* {job.requested_outputs?.transcreation && job.requested_outputs.transcreation.length > 0 && (
                  <div className="sm:col-span-2">
                    <dt className="text-sm font-medium text-gray-500">Transcreation Languages</dt>
                    <dd className="text-sm text-gray-900 mt-1">
                      {job.requested_outputs.transcreation.join(', ')} (Cultural adaptation)
                    </dd>
                  </div>
                )} */}
              </dl>
            </div>

            {/* Review Notes */}
            {(() => {
              const notesEntries = job.review?.history?.filter(entry => entry.notes && entry.notes.trim()) || [];
              return (
                <div className="bg-white border border-gray-200 rounded-lg p-6">
                  <h2 className="text-lg font-medium text-gray-900 mb-4">Review Notes</h2>
                  {notesEntries.length > 0 ? (
                    <div className="space-y-3">
                      {notesEntries.map((entry, index) => (
                        <div key={index} className="p-3 bg-gray-50 rounded border-l-4 border-blue-400">
                          <div className="flex items-center justify-between mb-1">
                            <span className="text-xs font-medium text-gray-500 uppercase">
                              {entry.status.replace(/_/g, ' ')}
                            </span>
                            <span className="text-xs text-gray-400">
                              {formatDistanceToNow(new Date(entry.at))} ago
                            </span>
                          </div>
                          <p className="text-sm text-gray-800">{entry.notes}</p>
                        </div>
                      ))}
                    </div>
                  ) : (
                    <p className="text-sm text-gray-400">No review notes yet</p>
                  )}
                </div>
              );
            })()}

            {/* Download Section */}
            {job.status === 'completed' && (
              <div className="bg-green-50 border border-green-200 rounded-lg p-6">
                <div className="flex items-center justify-between">
                  <div>
                    <h3 className="text-lg font-medium text-green-800">Ready for Download</h3>
                    <p className="text-green-700 text-sm mt-1">
                      Your accessible video assets are ready. Click below to access your files.
                    </p>
                  </div>
                  <Link
                    to={`/downloads/${job.id}`}
                    className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-green-600 hover:bg-green-700"
                  >
                    <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="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 Files
                  </Link>
                </div>
              </div>
            )}
          </div>
        );

      case 'video':
        return (
          <div className="bg-white border border-gray-200 rounded-lg p-6">
            <h2 className="text-lg font-medium text-gray-900 mb-4">Video Preview</h2>
            {videoUrl ? (
              <VideoWithCaptions
                videoUrl={videoUrl}
                captionsVtt={sourceVtt?.captions_vtt || ''}
                audioDescriptionVtt={sourceVtt?.audio_description_vtt || ''}
                sourceLanguage={sourceLanguage}
              />
            ) : (
              <div className="text-center py-8 text-gray-500">
                <svg className="w-12 h-12 mx-auto mb-4 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 10l4.553-2.276A1 1 0 0121 8.618v6.764a1 1 0 01-1.447.894L15 14M5 18h8a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v8a2 2 0 002 2z" />
                </svg>
                <p>Video preview will be available once processing begins</p>
              </div>
            )}
          </div>
        );

      case 'assets':
        return (
          <div className="space-y-6">
            {/* Language Assets */}
            {job.outputs && Object.keys(job.outputs).length > 0 && (
              <div className="bg-white border border-gray-200 rounded-lg p-6">
                <h2 className="text-lg font-medium text-gray-900 mb-4">Language Assets</h2>
                <div className="space-y-4">
                  {Object.entries(job.outputs).map(([language, output]) => {
                    const assets = output as {
                      captions_vtt_gcs?: string;
                      ad_vtt_gcs?: string;
                      ad_mp3_gcs?: string;
                      qa_notes?: string;
                    };
                    return (
                      <div key={language} className="border border-gray-200 rounded-lg p-4">
                        <div className="flex items-center justify-between mb-3">
                          <h3 className="font-medium text-gray-900">{language.toUpperCase()}</h3>
                          <div className="flex items-center space-x-2">
                            {assets.captions_vtt_gcs && (
                              <span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-green-100 text-green-800">
                                Captions Ready
                              </span>
                            )}
                            {assets.ad_vtt_gcs && (
                              <span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-blue-100 text-blue-800">
                                AD Ready
                              </span>
                            )}
                            {assets.ad_mp3_gcs && (
                              <span className="inline-flex items-center px-2 py-1 rounded text-xs font-medium bg-purple-100 text-purple-800">
                                MP3 Ready
                              </span>
                            )}
                          </div>
                        </div>
                        {assets.qa_notes && (
                          <div className="mt-2 p-2 bg-red-50 border border-red-200 rounded">
                            <p className="text-sm text-red-800">
                              <strong>QA Issues:</strong> {assets.qa_notes}
                            </p>
                          </div>
                        )}
                      </div>
                    );
                  })}
                </div>
              </div>
            )}
          </div>
        );

      case 'history':
        return (
          <div className="bg-white border border-gray-200 rounded-lg p-6">
            <h2 className="text-lg font-medium text-gray-900 mb-4">Processing History</h2>
            <div className="space-y-3">
              {job.review?.history?.map((entry, index) => (
                <div key={index} className="flex items-center justify-between text-sm p-3 bg-gray-50 rounded">
                  <div className="flex items-center space-x-3">
                    <span className="text-gray-900 font-medium">
                      {entry.status.replace(/_/g, ' ').toUpperCase()}
                    </span>
                    {entry.notes && (
                      <span className="text-gray-600">- {entry.notes}</span>
                    )}
                  </div>
                  <span className="text-gray-500">
                    {formatDistanceToNow(new Date(entry.at))} ago
                  </span>
                </div>
              )) || (
                <p className="text-gray-500 text-sm">No history available</p>
              )}
            </div>
          </div>
        );

      case 'versions': {
        const outputLangs = job.outputs ? Object.keys(job.outputs) : [sourceLanguage];
        return (
          <VersionsTab
            jobId={id!}
            languages={outputLangs}
            defaultLang={sourceLanguage}
          />
        );
      }

      default:
        return null;
    }
  };

  return (
    <div className="container mx-auto px-4 py-8">
      {/* Header */}
      <div className="mb-8">
        <div className="flex items-center justify-between">
          <div>
            <div className="flex items-center gap-2 mb-2">
              {editingTitle ? (
                <input
                  type="text"
                  value={titleDraft}
                  onChange={e => setTitleDraft(e.target.value)}
                  onKeyDown={e => { if (e.key === 'Enter') handleTitleSave(); if (e.key === 'Escape') setEditingTitle(false); }}
                  onBlur={handleTitleSave}
                  className="text-3xl font-bold text-gray-900 border-b-2 border-indigo-500 focus:outline-none bg-transparent w-full"
                  autoFocus
                />
              ) : (
                <h1 className="text-3xl font-bold text-gray-900">{job.title}</h1>
              )}
              {canEditTitle && !editingTitle && (
                <button
                  onClick={() => { setTitleDraft(job.title); setEditingTitle(true); }}
                  className="text-gray-400 hover:text-gray-600 flex-shrink-0"
                  title="Rename"
                >
                  <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
                  </svg>
                </button>
              )}
            </div>
            <p className="text-gray-600">
              {job.source?.original_filename} •
              Created {formatDistanceToNow(new Date(job.created_at))} ago
            </p>
          </div>
          <div className="flex items-center gap-2">
            <StatusBadge status={job.status} />
            {connectionStatus === 'connected' && (
              <span className="inline-block w-2 h-2 bg-green-400 rounded-full" title="Connected - receiving real-time updates" />
            )}
            {connectionStatus === 'connecting' && (
              <span className="inline-block w-2 h-2 bg-yellow-400 rounded-full animate-pulse" title="Connecting..." />
            )}
            {connectionStatus === 'error' && (
              <span className="inline-block w-2 h-2 bg-red-400 rounded-full" title="Connection error" />
            )}
          </div>
        </div>
      </div>

      <div className="grid gap-6 lg:grid-cols-4">
        <div className="lg:col-span-3">
          {/* Tab Navigation */}
          <div className="border-b border-gray-200 mb-6">
            <nav className="-mb-px flex space-x-8">
              {tabs.map((tab) => (
                <button
                  key={tab.id}
                  onClick={() => setActiveTab(tab.id)}
                  disabled={tab.disabled}
                  className={`py-2 px-1 border-b-2 font-medium text-sm ${
                    activeTab === tab.id
                      ? 'border-blue-500 text-blue-600'
                      : tab.disabled
                      ? 'border-transparent text-gray-400 cursor-not-allowed'
                      : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'
                  }`}
                >
                  <span className="mr-2">{tab.icon}</span>
                  {tab.label}
                </button>
              ))}
            </nav>
          </div>

          {/* Tab Content */}
          {renderTabContent()}

          {/* Review Action Button */}
          {job.status === 'pending_qc' && (
            <div className="mt-8 bg-blue-50 border border-blue-200 rounded-lg p-6">
              <div className="flex items-center justify-between">
                <div>
                  <h3 className="text-lg font-medium text-blue-800">Ready for QC Review</h3>
                  <p className="text-blue-700 text-sm mt-1">
                    This job is awaiting quality control review. Review and approve the captions and audio descriptions.
                  </p>
                </div>
                <Link
                  to={`/admin/qc/${job.id}`}
                  className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-blue-600 hover:bg-blue-700 shadow-sm"
                >
                  <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-6 9l2 2 4-4" />
                  </svg>
                  Go to QC Review
                </Link>
              </div>
            </div>
          )}

          {job.status === 'pending_final_review' && (
            <div className="mt-8 bg-purple-50 border border-purple-200 rounded-lg p-6">
              <div className="flex items-center justify-between">
                <div>
                  <h3 className="text-lg font-medium text-purple-800">Ready for Final Review</h3>
                  <p className="text-purple-700 text-sm mt-1">
                    All translations and audio are complete. Perform the final review before delivery.
                  </p>
                </div>
                <Link
                  to={`/admin/final/${job.id}`}
                  className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-purple-600 hover:bg-purple-700 shadow-sm"
                >
                  <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
                  </svg>
                  Go to Final Review
                </Link>
              </div>
            </div>
          )}

          {/* Return to QC */}
          {canReturnToQC && (
            <div className="mt-8 bg-amber-50 border border-amber-200 rounded-lg p-6">
              {!showReturnToQC ? (
                <div className="flex items-center justify-between">
                  <div>
                    <h3 className="text-lg font-medium text-amber-800">Return to QC</h3>
                    <p className="text-amber-700 text-sm mt-1">
                      Move this job back to QC review for further editing.
                    </p>
                  </div>
                  <button
                    onClick={() => setShowReturnToQC(true)}
                    className="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-amber-600 hover:bg-amber-700 shadow-sm"
                  >
                    <svg className="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                      <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" />
                    </svg>
                    Return to QC
                  </button>
                </div>
              ) : (
                <div>
                  <h3 className="text-lg font-medium text-amber-800 mb-3">Return to QC</h3>
                  <p className="text-amber-700 text-sm mb-3">
                    This will move the job back to QC review status. Please provide a reason.
                  </p>
                  <textarea
                    value={returnToQCNotes}
                    onChange={(e) => setReturnToQCNotes(e.target.value)}
                    placeholder="Reason for returning to QC..."
                    rows={3}
                    className="w-full px-3 py-2 border border-amber-300 rounded-md focus:outline-none focus:ring-2 focus:ring-amber-500 mb-3"
                  />
                  <div className="flex items-center space-x-3">
                    <button
                      onClick={handleReturnToQC}
                      disabled={!returnToQCNotes.trim() || returnToQCMutation.isPending}
                      className="px-4 py-2 bg-amber-600 text-white text-sm font-medium rounded-md hover:bg-amber-700 disabled:opacity-50 disabled:cursor-not-allowed"
                    >
                      {returnToQCMutation.isPending ? 'Returning...' : 'Confirm Return to QC'}
                    </button>
                    <button
                      onClick={() => { setShowReturnToQC(false); setReturnToQCNotes(''); }}
                      className="px-4 py-2 text-gray-600 text-sm font-medium hover:text-gray-800"
                    >
                      Cancel
                    </button>
                  </div>
                </div>
              )}
            </div>
          )}
        </div>

        {/* Sidebar */}
        <div className="space-y-6">
          <ProgressIndicator status={job.status} failure={job.failure} />

          {/* Stop Process */}
          {canCancel && (
            <div>
              {!showCancelConfirm ? (
                <button
                  onClick={() => setShowCancelConfirm(true)}
                  className="w-full inline-flex items-center justify-center px-4 py-2 border border-red-300 text-sm font-medium rounded-md text-red-700 bg-white hover:bg-red-50"
                >
                  <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="M6 18L18 6M6 6l12 12" />
                  </svg>
                  Stop Process
                </button>
              ) : (
                <div className="bg-red-50 border border-red-200 rounded-lg p-4">
                  <p className="text-sm text-red-800 font-medium mb-1">Stop this job?</p>
                  <p className="text-xs text-red-600 mb-3">The pipeline will be interrupted. You can retry it later.</p>
                  <div className="flex gap-2">
                    <button
                      onClick={handleCancelJob}
                      disabled={cancelJobMutation.isPending}
                      className="flex-1 px-3 py-1.5 text-sm font-medium rounded-md text-white bg-red-600 hover:bg-red-700 disabled:opacity-50"
                    >
                      {cancelJobMutation.isPending ? 'Stopping…' : 'Yes, stop it'}
                    </button>
                    <button
                      onClick={() => setShowCancelConfirm(false)}
                      className="flex-1 px-3 py-1.5 text-sm font-medium rounded-md text-gray-700 bg-white border border-gray-300 hover:bg-gray-50"
                    >
                      Keep running
                    </button>
                  </div>
                </div>
              )}
            </div>
          )}

          {/* Error Display */}
          {job.error && isFailedStatus && (
            <div className="bg-red-50 border border-red-200 rounded-lg p-4">
              <div className="flex items-start gap-2 mb-2">
                <svg className="w-5 h-5 text-red-600 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                </svg>
                <h3 className="text-sm font-medium text-red-800">Processing Error</h3>
              </div>
              <p className="text-sm text-red-700 mb-2">
                {String(job.error.message || 'An error occurred during processing')}
              </p>
              {job.error.type ? (
                <p className="text-xs text-red-600 mb-2">
                  <span className="font-medium">Type:</span> {String(job.error.type).replace(/_/g, ' ')}
                </p>
              ) : null}
              {/* Show TTS-specific error details */}
              {job.error.type === 'tts_synthesis_failure' && (
                <div className="mt-3 pt-3 border-t border-red-200">
                  <p className="text-xs font-medium text-red-800 mb-2">TTS Synthesis Failed</p>
                  {typeof job.error.cue_index === 'number' && (
                    <p className="text-xs text-red-600 mb-1">
                      <span className="font-medium">Failed Cue:</span> #{(job.error.cue_index as number) + 1}
                    </p>
                  )}
                  {typeof job.error.cue_text === 'string' && (
                    <div className="mt-2 p-2 bg-red-100 rounded text-xs text-red-700">
                      <span className="font-medium">Cue Text (after rewrite attempt):</span>
                      <p className="mt-1 italic">"{job.error.cue_text}"</p>
                    </div>
                  )}
                  <p className="text-xs text-red-600 mt-2">
                    This cue failed even after automatic rewriting. Manual editing may be required.
                  </p>
                </div>
              )}
              {/* Show failed languages for render failures */}
              {Array.isArray(job.error.failed_languages) ? (
                <div className="mt-3 pt-3 border-t border-red-200">
                  <p className="text-xs font-medium text-red-800 mb-2">Failed Languages:</p>
                  <ul className="space-y-1">
                    {(job.error.failed_languages as Array<{language: string; error: string}>).map((item, idx) => (
                      <li key={idx} className="text-xs text-red-600">
                        <span className="font-medium">{String(item.language).toUpperCase()}:</span> {String(item.error)}
                      </li>
                    ))}
                  </ul>
                </div>
              ) : null}
              {job.error.timestamp ? (
                <p className="text-xs text-red-500 mt-2">
                  {formatDistanceToNow(new Date(String(job.error.timestamp)))} ago
                </p>
              ) : null}
            </div>
          )}

          {/* TTS Rewrites Caution Display */}
          {job.tts_rewrites && job.tts_rewrites.length > 0 && (
            <div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
              <div className="flex items-start gap-2 mb-2">
                <svg className="w-5 h-5 text-amber-600 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" />
                </svg>
                <h3 className="text-sm font-medium text-amber-800">Audio Description Rewrites</h3>
              </div>
              <p className="text-xs text-amber-700 mb-3">
                {job.tts_rewrites.length} cue{job.tts_rewrites.length > 1 ? 's were' : ' was'} automatically rewritten to pass TTS synthesis.
                Please review for accuracy.
              </p>
              <div className="space-y-3 max-h-64 overflow-y-auto">
                {job.tts_rewrites.map((rewrite, idx) => (
                  <div key={idx} className="border-t border-amber-200 pt-2">
                    <p className="text-xs text-amber-800 font-medium">
                      {rewrite.language.toUpperCase()} - Cue #{rewrite.cue_index + 1}
                    </p>
                    <div className="mt-1 grid grid-cols-1 gap-2">
                      <div className="p-2 bg-amber-100 rounded text-xs">
                        <span className="font-medium text-amber-700">Original:</span>
                        <p className="mt-1 text-amber-800 line-through">"{rewrite.original_text}"</p>
                      </div>
                      <div className="p-2 bg-green-100 rounded text-xs">
                        <span className="font-medium text-green-700">Rewritten:</span>
                        <p className="mt-1 text-green-800">"{rewrite.rewritten_text}"</p>
                      </div>
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}

          {/* Failure banner — shown for any failed status */}
          {isFailedStatus && (
            <div className="bg-red-50 border border-red-200 rounded-lg p-4">
              <h3 className="text-sm font-medium text-red-800 mb-2">Processing Failed</h3>
              {job.failure ? (
                <div className="mb-3 space-y-1">
                  <p className="text-xs text-red-700">
                    <span className="font-medium">Step:</span> {job.failure.step.replace(/_/g, ' ')}
                  </p>
                  <p className="text-xs text-red-700 break-words">
                    <span className="font-medium">Error:</span> {job.failure.message}
                  </p>
                  {(job.failure.retry_count ?? 0) > 0 && (
                    <p className={`text-xs font-medium ${job.failure.retry_count > 3 ? 'text-red-800' : 'text-orange-700'}`}>
                      Retried {job.failure.retry_count} time{job.failure.retry_count !== 1 ? 's' : ''}.
                      {job.failure.retry_count > 3 && ' Consider escalating.'}
                    </p>
                  )}
                </div>
              ) : (
                <p className="text-xs text-red-700 mb-3">
                  {job.status === 'tts_failed'
                    ? 'TTS generation failed. Fix audio description text before retrying.'
                    : job.status === 'render_failed'
                    ? 'Video rendering failed.'
                    : typeof job.error === 'string' && job.error
                    ? job.error
                    : 'Processing failed. Retry or escalate to support.'}
                </p>
              )}
              <div className="flex gap-2">
                <button
                  onClick={handleRetryJob}
                  disabled={retryJobMutation.isPending}
                  className="flex-1 px-3 py-2 text-sm bg-red-600 text-white rounded hover:bg-red-700 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
                >
                  {retryJobMutation.isPending ? 'Retrying...' : 'Retry'}
                </button>
                <a
                  href={`mailto:support@oliver.agency?subject=Job%20${id}%20failure&body=Job%20${id}%20(${job.title})%20failed%20at%20step%3A%20${job.failure?.step ?? job.status}`}
                  className="px-3 py-2 text-sm bg-gray-200 text-gray-700 rounded hover:bg-gray-300 transition-colors"
                >
                  Escalate
                </a>
              </div>
            </div>
          )}
        </div>
      </div>
    </div>
  );
}