import React, { useEffect, useState, useRef } from 'react';
import { useParams, useNavigate, Link } from 'react-router-dom';
import { ArrowLeft, Download, FileText, CheckCircle, Clock, XCircle } from 'lucide-react';
import invoiceService, { Invoice } from '../../features/payments/services/invoiceService';
import { toast } from 'react-toastify';
import Loading from '../../shared/components/Loading';
import { useFormatCurrency } from '../../features/payments/hooks/useFormatCurrency';
import { formatDate } from '../../shared/utils/format';
import useAuthStore from '../../store/useAuthStore';
import { validateInvoiceId } from '../../shared/utils/routeValidation';

const InvoicePage: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const { formatCurrency } = useFormatCurrency();
  const { userInfo } = useAuthStore();
  const [invoice, setInvoice] = useState<Invoice | null>(null);
  const [loading, setLoading] = useState(true);
  const abortControllerRef = useRef<AbortController | null>(null);

  // Validate route parameter and fetch invoice
  useEffect(() => {
    const invoiceId = validateInvoiceId(id);
    
    if (!invoiceId) {
      setLoading(false);
      // Redirect based on user role
      if (userInfo?.role === 'admin') {
        navigate('/admin/bookings?createInvoice=true');
      } else if (userInfo?.role === 'staff') {
        navigate('/staff/bookings?createInvoice=true');
      } else if (userInfo?.role === 'accountant') {
        navigate('/accountant/invoices');
      } else {
        navigate('/bookings');
      }
      return;
    }

    // Cancel previous request if exists
    if (abortControllerRef.current) {
      abortControllerRef.current.abort();
    }

    // Create new abort controller
    abortControllerRef.current = new AbortController();

    fetchInvoice(invoiceId);

    // Cleanup: abort request on unmount
    return () => {
      if (abortControllerRef.current) {
        abortControllerRef.current.abort();
      }
    };
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [id, navigate, userInfo?.role]);

  const fetchInvoice = async (invoiceId: number, retryCount: number = 0) => {
    try {
      setLoading(true);
      const response = await invoiceService.getInvoiceById(invoiceId);
      
      if (response.status === 'success' && response.data?.invoice) {
        const invoiceData = response.data.invoice;
        
        // Validate ownership for customer role
        if (userInfo?.role === 'customer' && invoiceData.booking?.user_id !== userInfo.id) {
          toast.error('You do not have permission to view this invoice');
          navigate('/bookings');
          setLoading(false);
          return;
        }
        
        setInvoice(invoiceData);
        setLoading(false);
      } else {
        // Invoice not found in response - retry if first attempt
        if (retryCount === 0) {
          setTimeout(() => {
            fetchInvoice(invoiceId, 1);
          }, 500);
          return;
        }
        handleInvoiceNotFound();
      }
    } catch (error: unknown) {
      const isAbortError = (e: unknown): boolean => {
        if (typeof e === 'object' && e !== null) {
          const err = e as { name?: string; code?: string };
          return err.name === 'AbortError' || err.code === 'ERR_CANCELED';
        }
        return false;
      };
      if (isAbortError(error)) {
        return;
      }
      // Check if it's the "Invalid invoice ID" error from validation
      const errorMessage = getUserFriendlyError(error) || getUserFriendlyError(error) || '';
      if (errorMessage.includes('Invalid invoice ID') || errorMessage.includes('Invalid Invoice ID')) {
        // This is a validation error - don't show toast, just redirect silently
        setLoading(false);
        if (userInfo?.role === 'admin' || userInfo?.role === 'staff' || userInfo?.role === 'accountant') {
          navigate('/admin/bookings?createInvoice=true');
        } else {
          navigate('/bookings');
        }
        return;
      }
      
      // If it's a 404 and we haven't retried yet, retry multiple times with increasing delays
      // This handles cases where invoice was just created and might not be immediately available
      if (getUserFriendlyError(error) === 404 && retryCount < 3) {
        // Wait with increasing delay (500ms, 1000ms, 2000ms)
        const delay = 500 * Math.pow(2, retryCount);
        setTimeout(() => {
          fetchInvoice(invoiceId, retryCount + 1);
        }, delay);
        return;
      }
      
      // Handle invoice not found (404) after retries - show appropriate message
      if (getUserFriendlyError(error) === 404) {
        handleInvoiceNotFound();
      } else {
        // Other errors (network, server errors, etc.) - only show toast if not a validation error
        if (!errorMessage.includes('Invalid')) {
          toast.error(getUserFriendlyError(error) || 'Unable to load invoice');
        }
        setLoading(false);
        if (userInfo?.role === 'admin' || userInfo?.role === 'staff' || userInfo?.role === 'accountant') {
          navigate('/admin/bookings?createInvoice=true');
        } else {
          navigate('/bookings');
        }
      }
    }
  };

  const handleInvoiceNotFound = () => {
    setLoading(false);
    // Don't show error toast - just show the "not found" UI or redirect
    // The component will show the "Invoice Not Found" UI if invoice is null
    if (userInfo?.role === 'admin' || userInfo?.role === 'staff' || userInfo?.role === 'accountant') {
      // For admin/staff, redirect to bookings to create invoice
      navigate('/admin/bookings?createInvoice=true');
    }
    // For customers, the component will show the "Invoice Not Found" message
  };

  const getStatusIcon = (status: string) => {
    switch (status) {
      case 'paid':
        return <CheckCircle className="w-5 h-5 text-green-600" />;
      case 'sent':
      case 'draft':
        return <Clock className="w-5 h-5 text-yellow-600" />;
      case 'overdue':
        return <XCircle className="w-5 h-5 text-red-600" />;
      default:
        return <FileText className="w-5 h-5 text-gray-600" />;
    }
  };

  const getStatusColor = (status: string) => {
    switch (status) {
      case 'paid':
        return 'bg-green-100 text-green-800 border-green-200';
      case 'sent':
        return 'bg-blue-100 text-blue-800 border-blue-200';
      case 'draft':
        return 'bg-gray-100 text-gray-800 border-gray-200';
      case 'overdue':
        return 'bg-red-100 text-red-800 border-red-200';
      case 'cancelled':
        return 'bg-gray-100 text-gray-800 border-gray-200';
      default:
        return 'bg-gray-100 text-gray-800 border-gray-200';
    }
  };

  const handlePrint = () => {
    window.print();
  };

  if (loading) {
    return <Loading fullScreen text="Loading invoice..." />;
  }

  if (!invoice && !loading) {
    return (
      <div className="min-h-screen bg-gray-50 py-8">
        <div className="max-w-4xl mx-auto px-4">
          <div className="bg-white rounded-lg shadow-md p-8 text-center">
            <FileText className="w-16 h-16 text-gray-400 mx-auto mb-4" />
            <h2 className="text-2xl font-bold text-gray-900 mb-2">Invoice Not Found</h2>
            <p className="text-gray-600 mb-6">
              {userInfo?.role === 'admin' || userInfo?.role === 'staff' || userInfo?.role === 'accountant'
                ? 'No invoice found for this ID. You can create an invoice from the bookings page.'
                : 'The invoice you\'re looking for doesn\'t exist.'}
            </p>
            {userInfo?.role === 'admin' || userInfo?.role === 'staff' || userInfo?.role === 'accountant' ? (
              <Link
                to="/admin/bookings?createInvoice=true"
                className="inline-flex items-center gap-2 px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
              >
                <FileText className="w-5 h-5" />
                Create Invoice from Booking
              </Link>
            ) : (
              <Link
                to="/bookings"
                className="inline-flex items-center gap-2 px-6 py-3 bg-blue-600 text-white rounded-lg hover:bg-blue-700 transition-colors"
              >
                <ArrowLeft className="w-5 h-5" />
                Back to Bookings
              </Link>
            )}
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="min-h-screen bg-gray-50 py-8 print:bg-white">
      <div className="max-w-4xl mx-auto px-4">
        {}
        <div className="mb-6 flex items-center justify-between print:hidden">
          <Link
            to="/bookings"
            className="inline-flex items-center gap-2 text-gray-600 hover:text-gray-900 transition-colors"
          >
            <ArrowLeft className="w-5 h-5" />
            <span>Back to Bookings</span>
          </Link>
          <div className="flex items-center gap-3">
            <button
              onClick={handlePrint}
              className="inline-flex items-center gap-2 px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors"
            >
              <Download className="w-5 h-5" />
              Print/Download
            </button>
          </div>
        </div>

        {}
        <div className="bg-white rounded-lg shadow-lg p-8 print:shadow-none">
          {}
          <div className="flex justify-between items-start mb-8 pb-8 border-b-2 border-gray-200">
            <div>
              <h1 className="text-3xl font-bold text-gray-900 mb-2">
                {invoice.is_proforma ? 'Proforma Invoice' : 'Invoice'}
              </h1>
              <p className="text-gray-600">#{invoice.invoice_number}</p>
              {invoice.promotion_code && (
                <div className="mt-2">
                  <span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-semibold bg-gradient-to-r from-purple-100 to-pink-100 text-purple-700 border border-purple-200">
                    Promotion Code: {invoice.promotion_code}
                  </span>
                </div>
              )}
            </div>
            <div className={`flex items-center gap-2 px-4 py-2 rounded-lg border ${getStatusColor(invoice.status)}`}>
              {getStatusIcon(invoice.status)}
              <span className="font-medium capitalize">{invoice.status}</span>
            </div>
          </div>

          {}
          <div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-8">
            {}
            <div>
              <h3 className="text-sm font-semibold text-gray-500 uppercase mb-3">From</h3>
              {invoice.company_name && (
                <div className="text-gray-900">
                  <p className="font-bold text-lg mb-1">{invoice.company_name}</p>
                  {invoice.company_address && (
                    <p className="text-gray-600 whitespace-pre-line">{invoice.company_address}</p>
                  )}
                  <div className="mt-2 space-y-1">
                    {invoice.company_phone && (
                      <p className="text-gray-600">Phone: {invoice.company_phone}</p>
                    )}
                    {invoice.company_email && (
                      <p className="text-gray-600">Email: {invoice.company_email}</p>
                    )}
                    {invoice.company_tax_id && (
                      <p className="text-gray-600">Tax ID: {invoice.company_tax_id}</p>
                    )}
                  </div>
                </div>
              )}
              {!invoice.company_name && (
                <p className="text-gray-500 italic">Company information not set</p>
              )}
            </div>

            {}
            <div>
              <h3 className="text-sm font-semibold text-gray-500 uppercase mb-3">Bill To</h3>
              <div className="text-gray-900">
                <p className="font-bold text-lg mb-1">{invoice.customer_name}</p>
                {invoice.customer_address && (
                  <p className="text-gray-600 whitespace-pre-line">{invoice.customer_address}</p>
                )}
                <div className="mt-2 space-y-1">
                  {invoice.customer_email && (
                    <p className="text-gray-600">Email: {invoice.customer_email}</p>
                  )}
                  {invoice.customer_phone && (
                    <p className="text-gray-600">Phone: {invoice.customer_phone}</p>
                  )}
                  {invoice.customer_tax_id && (
                    <p className="text-gray-600">Tax ID: {invoice.customer_tax_id}</p>
                  )}
                </div>
              </div>
            </div>
          </div>

          {}
          <div className="grid grid-cols-2 md:grid-cols-4 gap-4 mb-8 p-4 bg-gray-50 rounded-lg">
            <div>
              <p className="text-sm text-gray-500 mb-1">Issue Date</p>
              <p className="font-medium text-gray-900">{formatDate(invoice.issue_date, 'medium')}</p>
            </div>
            <div>
              <p className="text-sm text-gray-500 mb-1">Due Date</p>
              <p className="font-medium text-gray-900">{formatDate(invoice.due_date, 'medium')}</p>
            </div>
            {invoice.paid_date && (
              <div>
                <p className="text-sm text-gray-500 mb-1">Paid Date</p>
                <p className="font-medium text-gray-900">{formatDate(invoice.paid_date, 'medium')}</p>
              </div>
            )}
            <div>
              <p className="text-sm text-gray-500 mb-1">Booking ID</p>
              <p className="font-medium text-gray-900">#{invoice.booking_id}</p>
            </div>
          </div>

          {}
          <div className="mb-8">
            <h3 className="text-lg font-semibold text-gray-900 mb-4">Items</h3>
            <div className="overflow-x-auto">
              <table className="w-full">
                <thead className="bg-gray-50">
                  <tr>
                    <th className="px-4 py-3 text-left text-sm font-semibold text-gray-700">Description</th>
                    <th className="px-4 py-3 text-right text-sm font-semibold text-gray-700">Quantity</th>
                    <th className="px-4 py-3 text-right text-sm font-semibold text-gray-700">Unit Price</th>
                    <th className="px-4 py-3 text-right text-sm font-semibold text-gray-700">Total</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-gray-200">
                  {invoice.items && invoice.items.length > 0 ? (
                    invoice.items.map((item) => (
                      <tr key={item.id}>
                        <td className="px-4 py-3 text-sm text-gray-900">{item.description}</td>
                        <td className="px-4 py-3 text-sm text-gray-600 text-right">{item.quantity}</td>
                        <td className="px-4 py-3 text-sm text-gray-600 text-right">{formatCurrency(item.unit_price)}</td>
                        <td className="px-4 py-3 text-sm font-medium text-gray-900 text-right">{formatCurrency(item.line_total)}</td>
                      </tr>
                    ))
                  ) : (
                    <tr>
                      <td colSpan={4} className="px-4 py-8 text-center text-gray-500">
                        No items found
                      </td>
                    </tr>
                  )}
                </tbody>
              </table>
            </div>
          </div>

          {}
          <div className="flex justify-end mb-8">
            <div className="w-full md:w-1/2">
              <div className="space-y-2">
                <div className="flex justify-between text-gray-600">
                  <span>Subtotal:</span>
                  <span>{formatCurrency(invoice.subtotal)}</span>
                </div>
                {invoice.discount_amount > 0 && (
                  <div className="flex justify-between text-green-600 font-medium">
                    <span>
                      Discount{invoice.promotion_code ? ` (${invoice.promotion_code})` : ''}:
                    </span>
                    <span>-{formatCurrency(invoice.discount_amount)}</span>
                  </div>
                )}
                {invoice.tax_amount > 0 && (
                  <div className="flex justify-between text-gray-600">
                    <span>Tax ({invoice.tax_rate}%):</span>
                    <span>{formatCurrency(invoice.tax_amount)}</span>
                  </div>
                )}
                <div className="flex justify-between text-lg font-bold text-gray-900 pt-2 border-t-2 border-gray-200">
                  <span>Total:</span>
                  <span>{formatCurrency(invoice.total_amount)}</span>
                </div>
                {invoice.amount_paid > 0 && (
                  <div className="flex justify-between text-gray-600">
                    <span>Amount Paid:</span>
                    <span className="text-green-600">{formatCurrency(invoice.amount_paid)}</span>
                  </div>
                )}
                {invoice.balance_due > 0 && (
                  <div className="flex justify-between text-lg font-bold text-red-600 pt-2 border-t border-gray-200">
                    <span>Balance Due:</span>
                    <span>{formatCurrency(invoice.balance_due)}</span>
                  </div>
                )}
                {invoice.balance_due <= 0 && invoice.status === 'paid' && (
                  <div className="flex justify-between text-lg font-bold text-green-600 pt-2 border-t border-gray-200">
                    <span>Status:</span>
                    <span>Paid in Full</span>
                  </div>
                )}
              </div>
            </div>
          </div>

          {}
          {(invoice.notes || invoice.terms_and_conditions || invoice.payment_instructions) && (
            <div className="mt-8 pt-8 border-t-2 border-gray-200 space-y-4">
              {invoice.notes && (
                <div>
                  <h4 className="text-sm font-semibold text-gray-700 mb-2">Notes</h4>
                  <p className="text-gray-600 whitespace-pre-line">{invoice.notes}</p>
                </div>
              )}
              {invoice.payment_instructions && (
                <div>
                  <h4 className="text-sm font-semibold text-gray-700 mb-2">Payment Instructions</h4>
                  <p className="text-gray-600 whitespace-pre-line">{invoice.payment_instructions}</p>
                </div>
              )}
              {invoice.terms_and_conditions && (
                <div>
                  <h4 className="text-sm font-semibold text-gray-700 mb-2">Terms & Conditions</h4>
                  <p className="text-sm text-gray-600 whitespace-pre-line">{invoice.terms_and_conditions}</p>
                </div>
              )}
            </div>
          )}

          {}
          <div className="mt-8 pt-8 border-t border-gray-200 text-center text-sm text-gray-500">
            <p>Thank you for your business!</p>
            {invoice.company_name && (
              <p className="mt-1">{invoice.company_name}</p>
            )}
          </div>
        </div>
      </div>
    </div>
  );
};

export default InvoicePage;

