/**
 * Component: Request Card
 * Documentation: documentation/frontend/components.md
 */

'use client';

import React from 'react';
import Image from 'next/image';
import { StatusBadge } from './StatusBadge';
import { Button } from '@/components/ui/Button';
import { useCancelRequest } from '@/lib/hooks/useRequests';
import { cn } from '@/lib/utils/cn';
import { usePreferences } from '@/contexts/PreferencesContext';
import { AudiobookDetailsModal } from '@/components/audiobooks/AudiobookDetailsModal';
import { ConfirmModal } from '@/components/ui/ConfirmModal';
import { COMPLETED_STATUSES, CANCELLABLE_STATUSES } from '@/lib/constants/request-statuses';

interface RequestCardProps {
  request: {
    id: string;
    type?: 'audiobook' | 'ebook';
    status: string;
    progress: number;
    errorMessage?: string;
    createdAt: string;
    updatedAt: string;
    completedAt?: string;
    downloadAvailable?: boolean;
    releaseDate?: string | Date | null;
    audiobook: {
      id: string;
      audibleAsin?: string;
      title: string;
      author: string;
      coverArtUrl?: string;
      filePath?: string | null;
      fileFormat?: string | null;
    };
  };
  showActions?: boolean;
}

export function RequestCard({ request, showActions = true }: RequestCardProps) {
  const { cancelRequest, isLoading } = useCancelRequest();
  const { squareCovers } = usePreferences();
  const [showError, setShowError] = React.useState(false);
  const [showDetailsModal, setShowDetailsModal] = React.useState(false);
  const [coverError, setCoverError] = React.useState(false);
  const [confirmCancelOpen, setConfirmCancelOpen] = React.useState(false);

  const isAwaitingApproval = request.status === 'awaiting_approval';

  const requestType = request.type || 'audiobook';
  const isEbook = requestType === 'ebook';

  const isCompleted = COMPLETED_STATUSES.includes(request.status as typeof COMPLETED_STATUSES[number]);
  const canCancel = (CANCELLABLE_STATUSES as readonly string[]).includes(request.status);
  const isActive = ['searching', 'downloading', 'processing'].includes(request.status);
  const isFailed = request.status === 'failed';

  const releaseDateLabel = React.useMemo(() => {
    if (request.status !== 'awaiting_release' || !request.releaseDate) return null;
    const parsed = new Date(request.releaseDate);
    if (Number.isNaN(parsed.getTime())) return null;
    return parsed.toLocaleDateString('en-US', {
      month: 'short',
      day: 'numeric',
      year: 'numeric',
      timeZone: 'UTC',
    });
  }, [request.status, request.releaseDate]);

  const handleConfirmCancel = async () => {
    try {
      await cancelRequest(request.id);
      setConfirmCancelOpen(false);
    } catch (error) {
      console.error('Failed to cancel request:', error);
      setConfirmCancelOpen(false);
    }
  };

  const formatDate = (dateString: string) => {
    const date = new Date(dateString);
    const now = new Date();
    const diffMs = now.getTime() - date.getTime();
    const diffMins = Math.floor(diffMs / 60000);
    const diffHours = Math.floor(diffMs / 3600000);
    const diffDays = Math.floor(diffMs / 86400000);

    if (diffMins < 1) return 'Just now';
    if (diffMins < 60) return `${diffMins}m ago`;
    if (diffHours < 24) return `${diffHours}h ago`;
    if (diffDays === 1) return 'Yesterday';
    if (diffDays < 7) return `${diffDays}d ago`;

    return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' });
  };

  return (
    <div className="bg-white dark:bg-gray-800 rounded-lg shadow-md overflow-hidden hover:shadow-lg transition-shadow">
      <div className="flex gap-3 sm:gap-4 p-3 sm:p-4">
        {/* Cover Art */}
        <div className="flex-shrink-0">
          <div
            className={cn(
              'relative rounded overflow-hidden bg-gray-200 dark:bg-gray-700',
              squareCovers
                ? 'w-16 sm:w-24 aspect-square'
                : 'w-16 sm:w-24 aspect-[2/3]',
              request.audiobook.audibleAsin && 'cursor-pointer hover:opacity-90 transition-opacity'
            )}
            onClick={() => request.audiobook.audibleAsin && setShowDetailsModal(true)}
            role={request.audiobook.audibleAsin ? 'button' : undefined}
            tabIndex={request.audiobook.audibleAsin ? 0 : undefined}
            onKeyDown={(e) => e.key === 'Enter' && request.audiobook.audibleAsin && setShowDetailsModal(true)}
          >
            {request.audiobook.coverArtUrl && !coverError ? (
              <Image
                src={request.audiobook.coverArtUrl}
                alt={request.audiobook.title}
                fill
                className="object-cover"
                sizes="96px"
                onError={() => setCoverError(true)}
              />
            ) : isEbook ? (
              <div className="w-full h-full flex items-center justify-center">
                <svg
                  className="w-12 h-12"
                  style={{ color: '#f16f19' }}
                  fill="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path d="M6 2c-1.1 0-1.99.9-1.99 2L4 20c0 1.1.89 2 1.99 2H18c1.1 0 2-.9 2-2V8l-6-6H6zm7 7V3.5L18.5 9H13z" />
                </svg>
              </div>
            ) : (
              <Image
                src="/placeholder_cover.svg"
                alt={request.audiobook.title}
                fill
                className="object-cover"
                sizes="96px"
              />
            )}
          </div>
        </div>

        {/* Request Info */}
        <div className="flex-1 min-w-0 space-y-1.5 sm:space-y-2">
          {/* Title and Author */}
          <div>
            <h3 className="text-sm sm:text-base md:text-lg font-semibold text-gray-900 dark:text-gray-100 line-clamp-2">
              {request.audiobook.title}
            </h3>
            <p className="text-xs sm:text-sm text-gray-600 dark:text-gray-400 truncate">
              By {request.audiobook.author}
            </p>
          </div>

          {/* Status Badge and Type Badge */}
          <div className="flex items-center gap-2 flex-wrap">
            <StatusBadge status={request.status} progress={request.progress} />
            {releaseDateLabel && (
              <span className="text-xs text-gray-500 dark:text-gray-400">
                Releases {releaseDateLabel}
              </span>
            )}
            {isEbook && (
              <span
                className="inline-flex items-center gap-1 px-2 py-0.5 text-xs font-medium rounded-full"
                style={{ backgroundColor: '#f16f1920', color: '#f16f19' }}
              >
                <svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
                  <path d="M9 4.804A7.968 7.968 0 005.5 4c-1.255 0-2.443.29-3.5.804v10A7.969 7.969 0 015.5 14c1.669 0 3.218.51 4.5 1.385A7.962 7.962 0 0114.5 14c1.255 0 2.443.29 3.5.804v-10A7.968 7.968 0 0014.5 4c-1.255 0-2.443.29-3.5.804V12a1 1 0 11-2 0V4.804z" />
                </svg>
                Ebook
              </span>
            )}
            {isActive && request.progress > 0 && (
              <div className="flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400">
                <div className="animate-pulse w-2 h-2 bg-blue-500 rounded-full"></div>
                <span>Active</span>
              </div>
            )}
            {isActive && request.progress === 0 && (
              <div className="flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400">
                <div className="animate-spin w-3 h-3 border-2 border-gray-300 border-t-blue-500 rounded-full"></div>
                <span>Setting up...</span>
              </div>
            )}
          </div>

          {/* Progress Bar (for downloading/processing) */}
          {isActive && request.progress > 0 && (
            <div className="space-y-1">
              <div className="flex justify-between text-xs text-gray-600 dark:text-gray-400">
                <span>Progress</span>
                <span>{request.progress}%</span>
              </div>
              <div className="w-full bg-gray-200 dark:bg-gray-700 rounded-full h-2 overflow-hidden">
                <div
                  className={cn(
                    'h-full rounded-full transition-all duration-300',
                    request.status === 'downloading' ? 'bg-purple-600' : 'bg-orange-600'
                  )}
                  style={{ width: `${request.progress}%` }}
                />
              </div>
            </div>
          )}

          {/* Error Message */}
          {isFailed && request.errorMessage && (
            <div className="space-y-1">
              <button
                onClick={() => setShowError(!showError)}
                className="text-xs text-red-600 dark:text-red-400 hover:underline flex items-center gap-1"
              >
                <svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                  <path
                    strokeLinecap="round"
                    strokeLinejoin="round"
                    strokeWidth={2}
                    d={showError ? 'M19 9l-7 7-7-7' : 'M9 5l7 7-7 7'}
                  />
                </svg>
                {showError ? 'Hide error' : 'Show error'}
              </button>
              {showError && (
                <div className="text-xs text-red-600 dark:text-red-400 bg-red-50 dark:bg-red-900/20 p-2 rounded">
                  {request.errorMessage}
                </div>
              )}
            </div>
          )}

          {/* Timestamps and Actions */}
          <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 pt-2 border-t border-gray-200 dark:border-gray-700">
            <div className="text-xs text-gray-500 dark:text-gray-500">
              {request.completedAt
                ? `Completed ${formatDate(request.completedAt)}`
                : `Requested ${formatDate(request.createdAt)}`}
            </div>

            {/* Action Buttons */}
            {showActions && (
              <div className="flex flex-wrap gap-2">
                {canCancel && (
                  <Button
                    onClick={() => setConfirmCancelOpen(true)}
                    loading={isLoading}
                    variant="outline"
                    size="sm"
                    className="text-xs sm:text-sm text-red-600 border-red-600 hover:bg-red-50 dark:hover:bg-red-900/20"
                  >
                    {isAwaitingApproval ? 'Withdraw' : 'Cancel'}
                  </Button>
                )}
              </div>
            )}
          </div>
        </div>
      </div>

      {/* Audiobook Details Modal */}
      {request.audiobook.audibleAsin && (
        <AudiobookDetailsModal
          asin={request.audiobook.audibleAsin}
          isOpen={showDetailsModal}
          onClose={() => setShowDetailsModal(false)}
          requestStatus={request.status}
          isAvailable={COMPLETED_STATUSES.includes(request.status as typeof COMPLETED_STATUSES[number])}
        />
      )}

      <ConfirmModal
        isOpen={confirmCancelOpen}
        onClose={() => !isLoading && setConfirmCancelOpen(false)}
        onConfirm={handleConfirmCancel}
        title={isAwaitingApproval ? 'Withdraw request' : 'Cancel request'}
        message={
          isAwaitingApproval
            ? 'This request is pending admin approval and will be withdrawn. You can request it again later.'
            : 'This request has already been approved and is actively being processed. Cancelling will stop the download.'
        }
        confirmText={isAwaitingApproval ? 'Withdraw request' : 'Cancel request'}
        cancelText="Keep request"
        variant="danger"
        isLoading={isLoading}
      />
    </div>
  );
}
