'use client';

import React, { useMemo, useState } from 'react';
import { Button } from '@alga-psa/ui/components/Button';
import { Card } from '@alga-psa/ui/components/Card';
import { Package, FileText, AlertCircle, ScrollText } from 'lucide-react';
import BucketUsageChart from './BucketUsageChart';
import type {
  IClientContractLine,
  IQuoteWithClient,
} from '@alga-psa/types';
import type { InvoiceViewModel } from '@alga-psa/types';
import type { ClientBucketUsageResult } from '@alga-psa/client-portal/actions';
import { Skeleton } from '@alga-psa/ui/components/Skeleton';
import PlanDetailsDialog from './PlanDetailsDialog';
import { useTranslation } from '@alga-psa/ui/lib/i18n/client';
import { getRecurringServicePeriodSummary } from './recurringServicePeriodSummary';

// Flag to control visibility of bucket usage metrics
const SHOW_USAGE_FEATURES = true;

interface BillingOverviewTabProps {
  contractLine: IClientContractLine | null;
  invoices: InvoiceViewModel[];
  quotes: IQuoteWithClient[];
  bucketUsage: ClientBucketUsageResult[];
  isBucketUsageLoading: boolean;
  isLoading: boolean;
  formatCurrency: (amount: number, currencyCode?: string) => string;
  formatDate: (date: string | { toString(): string } | undefined | null) => string;
  onViewAllInvoices?: () => void;
  onViewAllQuotes?: () => void;
}

const BillingOverviewTab: React.FC<BillingOverviewTabProps> = React.memo(({
  contractLine,
  invoices,
  quotes,
  bucketUsage,
  isBucketUsageLoading,
  isLoading,
  formatCurrency,
  formatDate,
  onViewAllInvoices,
  onViewAllQuotes,
}) => {
  const { t } = useTranslation('features/billing');
  // State for plan details dialog
  const [isPlanDialogOpen, setIsPlanDialogOpen] = useState(false);
  const cadenceOwnerDescription = contractLine?.cadence_owner === 'contract'
    ? t(
      'contractLine.cadenceOwnerContractDescription',
      'Recurring service periods follow the contract anniversary cadence for this line.'
    )
    : t(
      'contractLine.cadenceOwnerClientDescription',
      'Recurring service periods follow the client billing schedule for this line.'
    );
  
  // Memoize the plan card to prevent unnecessary re-renders
  const planCard = useMemo(() => (
    <Card className="p-6">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-medium text-gray-500">{t('currentContractLine')}</p>
          {contractLine ? (
            <>
              <p className="mt-2 text-3xl font-semibold">{contractLine.contract_line_name}</p>
              <p className="mt-1 text-sm text-gray-500">{t(`frequency.${contractLine.billing_frequency?.toLowerCase() || 'monthly'}`)}</p>
              <p className="mt-2 text-sm text-gray-500">{cadenceOwnerDescription}</p>
            </>
          ) : (
            <>
              <Skeleton className="mt-2 h-8 w-3/4" />
              <Skeleton className="mt-1 h-4 w-1/2" />
            </>
          )}
        </div>
        <Package className="h-5 w-5 text-gray-400" />
      </div>
      <Button
        id="view-plan-details-button"
        className="mt-4 w-full"
        variant="outline"
        onClick={() => setIsPlanDialogOpen(true)}
      >
        {t('viewContractLineDetails')}
      </Button>
    </Card>
  ), [cadenceOwnerDescription, contractLine, t]);

  // Find the most recent unpaid invoice for the "Next Invoice" card
  const nextInvoice = useMemo(() => {
    // Filter to unpaid invoices and sort by due_date ascending to get the nearest due
    const unpaidInvoices = invoices.filter(inv =>
      inv.status !== 'paid' && inv.status !== 'cancelled'
    );
    if (unpaidInvoices.length === 0) return null;
    // Sort by due_date ascending (nearest due first)
    // due_date is DateValue type, convert to string first
    return unpaidInvoices.sort((a, b) => {
      const dateStrA = a.due_date ? String(a.due_date) : '';
      const dateStrB = b.due_date ? String(b.due_date) : '';
      const dateA = dateStrA ? new Date(dateStrA).getTime() : Infinity;
      const dateB = dateStrB ? new Date(dateStrB).getTime() : Infinity;
      return dateA - dateB;
    })[0];
  }, [invoices]);
  const nextInvoiceServicePeriodSummary = useMemo(() => {
    if (!nextInvoice) {
      return null;
    }

    return getRecurringServicePeriodSummary(nextInvoice, formatDate);
  }, [formatDate, nextInvoice]);
  const nextInvoiceFinancialArtifactSummary = useMemo(() => {
    if (!nextInvoice || nextInvoiceServicePeriodSummary) {
      return null;
    }

    if (nextInvoice.is_manual || Number(nextInvoice.credit_applied ?? 0) > 0) {
      return t(
        'invoice.financialArtifactSummary',
        'Financial-only invoice. Recurring service periods appear only on recurring detail lines.'
      );
    }

    return null;
  }, [nextInvoice, nextInvoiceServicePeriodSummary, t]);

  // Memoize the invoice card to prevent unnecessary re-renders
  const invoiceCard = useMemo(() => (
    <Card className="p-6">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-medium text-gray-500">{t('nextInvoice')}</p>
          {nextInvoice ? (
            <>
              <p className="mt-2 text-3xl font-semibold">
                {formatCurrency(nextInvoice.total_amount ?? 0, nextInvoice.currencyCode)}
              </p>
              <p className="mt-1 text-sm text-gray-500">
                {nextInvoice.due_date ? t('invoice.dueDateText', { date: formatDate(nextInvoice.due_date) }) : t('invoice.noDueDate')}
              </p>
              {nextInvoiceServicePeriodSummary ? (
                <p className="mt-2 text-sm text-gray-500">
                  {t('invoice.servicePeriod', 'Service Period')}: {nextInvoiceServicePeriodSummary}
                </p>
              ) : nextInvoiceFinancialArtifactSummary ? (
                <p className="mt-2 text-sm text-gray-500">{nextInvoiceFinancialArtifactSummary}</p>
              ) : null}
            </>
          ) : invoices.length > 0 ? (
            // All invoices are paid/cancelled
            <p className="mt-2 text-lg text-gray-500">{t('invoice.allPaid')}</p>
          ) : (
            <>
              <Skeleton className="mt-2 h-8 w-3/4" />
              <Skeleton className="mt-1 h-4 w-1/2" />
            </>
          )}
        </div>
        <FileText className="h-5 w-5 text-gray-400" />
      </div>
      <Button
        id="view-all-invoices-button"
        className="mt-4 w-full"
        variant="outline"
        onClick={() => {
          if (onViewAllInvoices) {
            onViewAllInvoices();
          }
        }}
      >
        {t('viewAllInvoices')}
      </Button>
    </Card>
  ), [nextInvoice, nextInvoiceFinancialArtifactSummary, nextInvoiceServicePeriodSummary, invoices.length, formatCurrency, formatDate, onViewAllInvoices, t]);

  const pendingQuotes = useMemo(
    () => quotes.filter((q) => q.status === 'sent' || q.status === 'approved'),
    [quotes]
  );

  const quotesCard = useMemo(() => (
    <Card className="p-6">
      <div className="flex items-start justify-between">
        <div>
          <p className="text-sm font-medium text-gray-500">{t('quotes.pendingQuotes', 'Pending Quotes')}</p>
          {isLoading ? (
            <>
              <Skeleton className="mt-2 h-8 w-3/4" />
              <Skeleton className="mt-1 h-4 w-1/2" />
            </>
          ) : pendingQuotes.length > 0 ? (
            <>
              <p className="mt-2 text-3xl font-semibold">{pendingQuotes.length}</p>
              <p className="mt-1 text-sm text-gray-500">
                {t('quotes.awaitingResponse', {
                  count: pendingQuotes.length,
                  defaultValue: '{{count}} quote(s) awaiting your response',
                })}
              </p>
              {pendingQuotes[0] && (
                <p className="mt-2 text-sm text-gray-500 truncate">
                  {pendingQuotes[0].title || pendingQuotes[0].quote_number}
                  {pendingQuotes[0].total_amount != null
                    ? ` — ${formatCurrency(pendingQuotes[0].total_amount, pendingQuotes[0].currency_code || 'USD')}`
                    : ''}
                </p>
              )}
            </>
          ) : (
            <p className="mt-2 text-lg text-gray-500">{t('quotes.noPending', 'No pending quotes')}</p>
          )}
        </div>
        <ScrollText className="h-5 w-5 text-gray-400" />
      </div>
      <Button
        id="view-all-quotes-button"
        className="mt-4 w-full"
        variant="outline"
        onClick={() => {
          if (onViewAllQuotes) {
            onViewAllQuotes();
          }
        }}
      >
        {t('quotes.viewAll', 'View All Quotes')}
      </Button>
    </Card>
  ), [pendingQuotes, isLoading, formatCurrency, onViewAllQuotes, t]);

  return (
    <>
      <div id="billing-overview-content" className="space-y-6 py-4">
        <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
          {planCard}
          {invoiceCard}
          {quotesCard}
        </div>

        {/* Enhanced Bucket Usage Visualization - optionally hidden */}
        {SHOW_USAGE_FEATURES && (
        <Card id="bucket-usage-card" className="p-6">
          <h3 className="text-lg font-semibold mb-4">{t('bucket.usage')}</h3>
          {isBucketUsageLoading || isLoading ? (
            // Client-side loading state with skeleton
            <div className="grid gap-6 md:grid-cols-2">
              {[...Array(2)].map((_, i) => (
                <div key={i} className="animate-pulse">
                  <Skeleton className="h-6 w-1/2 mb-2" />
                  <Skeleton className="h-4 w-1/3 mb-4" />
                  <Skeleton className="h-4 w-full mb-2" />
                  <Skeleton className="h-2 w-full mb-1" />
                  <div className="flex justify-between">
                    <Skeleton className="h-3 w-1/4" />
                    <Skeleton className="h-3 w-1/4" />
                  </div>
                </div>
              ))}
            </div>
          ) : bucketUsage.length === 0 ? (
            // Empty state
            <div className="flex items-center justify-center py-8">
              <div className="text-center">
                <AlertCircle className="mx-auto h-12 w-12 text-gray-400" />
                <h3 className="mt-2 text-lg font-medium text-gray-900">{t('bucket.noContractLineTitle')}</h3>
                <p className="mt-1 text-sm text-gray-500">
                  {t('bucket.noContractLineDescription')}
                </p>
              </div>
            </div>
          ) : (
            // Bucket usage charts - only rendered client-side
            <div className="grid gap-6 md:grid-cols-2">
              {bucketUsage.map((bucket, index) => (
                <BucketUsageChart key={`${bucket.contract_line_id}-${bucket.service_id}-${index}`} bucketData={bucket} />
              ))}
            </div>
          )}
        </Card>
        )}
      </div>

      {/* Plan Details Dialog */}
      <PlanDetailsDialog
        contractLine={contractLine}
        isOpen={isPlanDialogOpen}
        onClose={() => setIsPlanDialogOpen(false)}
        formatCurrency={formatCurrency}
        formatDate={formatDate}
      />
    </>
  );
});

// Add display name for debugging
BillingOverviewTab.displayName = 'BillingOverviewTab';

export default BillingOverviewTab;
