/**
 * Dealer Claim IO Tab
 * 
 * This component handles IO (Internal Order) management for dealer claims.
 * Located in: src/dealer-claim/components/request-detail/
 */

import { useState, useEffect } from 'react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import { DollarSign, Download, CircleCheckBig, Target } from 'lucide-react';
import { toast } from 'sonner';
import { validateIO, updateIODetails, getClaimDetails } from '@/services/dealerClaimApi';
import { useAuth } from '@/contexts/AuthContext';

interface IOTabProps {
  request: any;
  apiRequest?: any;
  onRefresh?: () => void;
}

interface IOBlockedDetails {
  ioNumber: string;
  blockedAmount: number;
  availableBalance: number; // Available amount before block
  remainingBalance: number; // Remaining amount after block
  blockedDate: string;
  blockedBy: string; // User who blocked
  sapDocumentNumber: string;
  status: 'blocked' | 'released' | 'failed';
}

export function IOTab({ request, apiRequest, onRefresh }: IOTabProps) {
  const { user } = useAuth();
  const requestId = apiRequest?.requestId || request?.requestId;
  
  // Load existing IO data from apiRequest or request
  const internalOrder = apiRequest?.internalOrder || apiRequest?.internal_order || null;
  const existingIONumber = internalOrder?.ioNumber || internalOrder?.io_number || request?.ioNumber || '';
  const existingBlockedAmount = internalOrder?.ioBlockedAmount || internalOrder?.io_blocked_amount || 0;
  const existingAvailableBalance = internalOrder?.ioAvailableBalance || internalOrder?.io_available_balance || 0;
  const existingRemainingBalance = internalOrder?.ioRemainingBalance || internalOrder?.io_remaining_balance || 0;
  const sapDocNumber = internalOrder?.sapDocumentNumber || internalOrder?.sap_document_number || '';
  // Get organizer user object from association (organizer) or fallback to organizedBy UUID
  const organizer = internalOrder?.organizer || null;
  
  // Get estimated budget from proposal details
  const proposalDetails = apiRequest?.proposalDetails || {};
  const estimatedBudget = Number(proposalDetails?.totalEstimatedBudget || proposalDetails?.total_estimated_budget || 0);
  
  const [ioNumber, setIoNumber] = useState(existingIONumber);
  const [fetchingAmount, setFetchingAmount] = useState(false);
  const [fetchedAmount, setFetchedAmount] = useState<number | null>(null);
  const [amountToBlock, setAmountToBlock] = useState<string>('');
  const [blockedDetails, setBlockedDetails] = useState<IOBlockedDetails | null>(null);
  const [blockingBudget, setBlockingBudget] = useState(false);

  // Load existing IO block details from apiRequest
  useEffect(() => {
    if (internalOrder && existingIONumber) {
      // IMPORTANT: ioAvailableBalance is already the available balance BEFORE blocking
      // We should NOT add blockedAmount to it - that would cause double deduction
      // Backend stores: availableBalance (before block), blockedAmount, remainingBalance (after block)
      const availableBeforeBlock = Number(existingAvailableBalance) || 0;
      
      // Get blocked by user name from organizer association (who blocked the amount)
      // When amount is blocked, organizedBy stores the user who blocked it
      const blockedByName = organizer?.displayName || 
                           organizer?.display_name || 
                           organizer?.name || 
                           (organizer?.firstName && organizer?.lastName ? `${organizer.firstName} ${organizer.lastName}`.trim() : null) ||
                           organizer?.email ||
                           'Unknown User';
      
      // Set IO number from existing data
      setIoNumber(existingIONumber);
      
      // Only set blocked details if amount is blocked
      if (existingBlockedAmount > 0) {
        const blockedAmt = Number(existingBlockedAmount) || 0;
        const backendRemaining = Number(existingRemainingBalance) || 0;
        
        // Calculate expected remaining balance for validation/debugging
        // Formula: remaining = availableBeforeBlock - blockedAmount
        const expectedRemaining = availableBeforeBlock - blockedAmt;
        
        // Loading existing IO block
        
        // Warn if remaining balance calculation seems incorrect (for backend debugging)
        if (Math.abs(backendRemaining - expectedRemaining) > 0.01) {
          console.warn('[IOTab] ⚠️ Remaining balance calculation issue detected!', {
            availableBalance: availableBeforeBlock,
            blockedAmount: blockedAmt,
            expectedRemaining,
            backendRemaining,
            difference: backendRemaining - expectedRemaining,
          });
        }
        
        setBlockedDetails({
          ioNumber: existingIONumber,
          blockedAmount: blockedAmt,
          availableBalance: availableBeforeBlock, // Available amount before block
          remainingBalance: backendRemaining, // Use backend calculated value
          blockedDate: internalOrder.organizedAt || internalOrder.organized_at || new Date().toISOString(),
          blockedBy: blockedByName,
          sapDocumentNumber: sapDocNumber,
          status: (internalOrder.status === 'BLOCKED' ? 'blocked' : 
                  internalOrder.status === 'RELEASED' ? 'released' : 'blocked') as 'blocked' | 'released' | 'failed',
        });
        
        // Set fetched amount if available balance exists
        if (availableBeforeBlock > 0) {
          setFetchedAmount(availableBeforeBlock);
        }
      }
    }
  }, [internalOrder, existingIONumber, existingBlockedAmount, existingAvailableBalance, existingRemainingBalance, sapDocNumber, organizer]);

  /**
   * Fetch available budget from SAP
   * Validates IO number and gets available balance (returns dummy data for now)
   * Does not store anything in database - only validates
   */
  const handleFetchAmount = async () => {
    if (!ioNumber.trim()) {
      toast.error('Please enter an IO number');
      return;
    }

    if (!requestId) {
      toast.error('Request ID not found');
      return;
    }

    setFetchingAmount(true);
    try {
      // Call validate IO endpoint - returns dummy data for now, will integrate with SAP later
      const ioData = await validateIO(requestId, ioNumber.trim());
      
      if (ioData.isValid && ioData.availableBalance > 0) {
        setFetchedAmount(ioData.availableBalance);
        // Pre-fill amount to block with estimated budget (if available), otherwise use available balance
        if (estimatedBudget > 0) {
          setAmountToBlock(String(estimatedBudget));
        } else {
          setAmountToBlock(String(ioData.availableBalance));
        }
        toast.success(`IO fetched from SAP. Available balance: ₹${ioData.availableBalance.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`);
      } else {
        toast.error('Invalid IO number or no available balance found');
        setFetchedAmount(null);
        setAmountToBlock('');
      }
    } catch (error: any) {
      console.error('Failed to fetch IO budget:', error);
      const errorMessage = error?.response?.data?.message || error?.message || 'Failed to validate IO number or fetch budget from SAP';
      toast.error(errorMessage);
      setFetchedAmount(null);
    } finally {
      setFetchingAmount(false);
    }
  };

  /**
   * Block budget in SAP system
   * This function:
   * 1. Validates the IO number and amount
   * 2. Calls SAP to block the budget
   * 3. Saves IO number, blocked amount, and balance details to database
   */
  const handleBlockBudget = async () => {
    if (!ioNumber.trim() || fetchedAmount === null) {
      toast.error('Please fetch IO amount first');
      return;
    }

    if (!requestId) {
      toast.error('Request ID not found');
      return;
    }

    const blockAmountRaw = parseFloat(amountToBlock);
    
    if (!amountToBlock || isNaN(blockAmountRaw) || blockAmountRaw <= 0) {
      toast.error('Please enter a valid amount to block');
      return;
    }
    
    // Round to exactly 2 decimal places to avoid floating point precision issues
    // Use parseFloat with toFixed to ensure exact 2 decimal precision
    const blockAmount = parseFloat(blockAmountRaw.toFixed(2));
    
    if (blockAmount > fetchedAmount) {
      toast.error('Amount to block exceeds available IO budget');
      return;
    }
    
    // Validate that amount to block must exactly match estimated budget
    if (estimatedBudget > 0) {
      const roundedEstimatedBudget = parseFloat(estimatedBudget.toFixed(2));
      if (Math.abs(blockAmount - roundedEstimatedBudget) > 0.01) {
        toast.error(`Amount to block must be exactly equal to the estimated budget (₹${roundedEstimatedBudget.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })})`);
        return;
      }
    }

    // Blocking budget

    setBlockingBudget(true);
    try {
      // Call updateIODetails with blockedAmount to block budget in SAP and store in database
      // This will store in internal_orders and claim_budget_tracking tables
      // Note: Backend will recalculate remainingBalance from SAP's response, so we pass it for reference only
      // Ensure all amounts are rounded to 2 decimal places for consistency
      const roundedFetchedAmount = parseFloat(fetchedAmount.toFixed(2));
      const calculatedRemaining = parseFloat((roundedFetchedAmount - blockAmount).toFixed(2));
      const payload = {
        ioNumber: ioNumber.trim(),
        ioAvailableBalance: roundedFetchedAmount,
        ioBlockedAmount: blockAmount,
        ioRemainingBalance: calculatedRemaining, // Calculated value (backend will use SAP's actual value)
      };
      
      // Sending to backend
      
      await updateIODetails(requestId, payload);
      
      // Fetch updated claim details to get the blocked IO data
      const claimData = await getClaimDetails(requestId);
      const updatedInternalOrder = claimData?.internalOrder || claimData?.internal_order;
      
      if (updatedInternalOrder) {
        const savedBlockedAmount = Number(updatedInternalOrder.ioBlockedAmount || updatedInternalOrder.io_blocked_amount || blockAmount);
        const savedRemainingBalance = Number(updatedInternalOrder.ioRemainingBalance || updatedInternalOrder.io_remaining_balance || 0);
        
        // Calculate expected remaining balance for validation/debugging
        const expectedRemainingBalance = fetchedAmount - savedBlockedAmount;
        
        // Blocking result processed
        
        // Warn if the saved amount differs from what we sent
        if (Math.abs(savedBlockedAmount - blockAmount) > 0.01) {
          console.warn('[IOTab] ⚠️ Amount mismatch! Sent:', blockAmount, 'Saved:', savedBlockedAmount);
        }
        
        // Warn if remaining balance calculation seems incorrect (for backend debugging)
        if (Math.abs(savedRemainingBalance - expectedRemainingBalance) > 0.01) {
          console.warn('[IOTab] ⚠️ Remaining balance calculation issue detected!', {
            availableBalance: fetchedAmount,
            blockedAmount: savedBlockedAmount,
            expectedRemaining: expectedRemainingBalance,
            backendRemaining: savedRemainingBalance,
            difference: savedRemainingBalance - expectedRemainingBalance,
          });
        }
        
        const currentUser = user as any;
        // When blocking, always use the current user who is performing the block action
        // The organizer association may be from initial IO organization, but we want who blocked the amount
        const blockedByName = currentUser?.displayName || 
                             currentUser?.display_name || 
                             currentUser?.name || 
                             (currentUser?.firstName && currentUser?.lastName ? `${currentUser.firstName} ${currentUser.lastName}`.trim() : null) ||
                             currentUser?.email || 
                             'Current User';
        
        const blocked: IOBlockedDetails = {
          ioNumber: updatedInternalOrder.ioNumber || updatedInternalOrder.io_number || ioNumber,
          blockedAmount: savedBlockedAmount,
          availableBalance: fetchedAmount, // Available amount before block
          remainingBalance: savedRemainingBalance,
          blockedDate: updatedInternalOrder.organizedAt || updatedInternalOrder.organized_at || new Date().toISOString(),
          blockedBy: blockedByName,
          sapDocumentNumber: updatedInternalOrder.sapDocumentNumber || updatedInternalOrder.sap_document_number || '',
          status: 'blocked',
        };
        
        setBlockedDetails(blocked);
        setAmountToBlock(''); // Clear the input
        toast.success('IO budget blocked successfully in SAP');
        
        // Refresh request details
        onRefresh?.();
      } else {
        toast.error('IO blocked but failed to fetch updated details');
        onRefresh?.();
      }
    } catch (error: any) {
      console.error('Failed to block IO budget:', error);
      const errorMessage = error?.response?.data?.message || error?.message || 'Failed to block IO budget in SAP';
      toast.error(errorMessage);
    } finally {
      setBlockingBudget(false);
    }
  };

  return (
    <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
      {/* IO Budget Management Card */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <DollarSign className="w-5 h-5 text-[#2d4a3e]" />
            IO Budget Management
          </CardTitle>
          <CardDescription>
            Enter IO number to fetch available budget from SAP
          </CardDescription>
        </CardHeader>
        <CardContent className="space-y-6">
          {/* IO Number Input */}
          <div className="space-y-3">
            <Label htmlFor="ioNumber">IO Number *</Label>
            <div className="flex gap-2">
              <Input
                id="ioNumber"
                placeholder="Enter IO number (e.g., IO-2024-12345)"
                value={ioNumber}
                onChange={(e) => setIoNumber(e.target.value)}
                disabled={fetchingAmount || !!blockedDetails}
                className="flex-1"
              />
              <Button
                onClick={handleFetchAmount}
                disabled={!ioNumber.trim() || fetchingAmount || !!blockedDetails}
                className="bg-[#2d4a3e] hover:bg-[#1f3329]"
              >
                <Download className="w-4 h-4 mr-2" />
                {fetchingAmount ? 'Fetching...' : 'Fetch Amount'}
              </Button>
            </div>
          </div>

          {/* Instructions when IO number is entered but not fetched */}
          {!fetchedAmount && !blockedDetails && ioNumber.trim() && (
            <div className="bg-blue-50 border border-blue-200 rounded-lg p-4">
              <p className="text-sm text-blue-800">
                <strong>Next Step:</strong> Click "Fetch Amount" to validate the IO number and get available balance from SAP.
              </p>
            </div>
          )}

          {/* Fetched Amount Display */}
          {fetchedAmount !== null && !blockedDetails && (
            <>
              <div className="bg-green-50 border-2 border-green-200 rounded-lg p-4">
                <div className="flex items-center justify-between">
                  <div>
                    <p className="text-xs text-gray-600 uppercase tracking-wide mb-1">Available Amount</p>
                    <p className="text-2xl font-bold text-green-700">
                      ₹{fetchedAmount.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                    </p>
                  </div>
                  <CircleCheckBig className="w-8 h-8 text-green-600" />
                </div>
                <div className="mt-3 pt-3 border-t border-green-200">
                  <p className="text-xs text-gray-600"><strong>IO Number:</strong> {ioNumber}</p>
                  <p className="text-xs text-gray-600 mt-1"><strong>Fetched from:</strong> SAP System</p>
                </div>
              </div>

              {/* Amount to Block Input */}
              <div className="space-y-3">
                <Label htmlFor="blockAmount">Amount to Block *</Label>
                <div className="relative">
                  <span className="absolute left-3 top-1/2 -translate-y-1/2 text-gray-500">₹</span>
                  <Input
                    type="number"
                    id="blockAmount"
                    placeholder="Enter amount to block"
                    min="0"
                    step="0.01"
                    value={amountToBlock}
                    onChange={(e) => setAmountToBlock(e.target.value)}
                    className="pl-8"
                  />
                </div>
                {estimatedBudget > 0 && (
                  <div className="bg-amber-50 border border-amber-200 rounded-lg p-3">
                    <p className="text-xs text-amber-800">
                      <strong>Required:</strong> Amount must be exactly equal to the estimated budget: <strong>₹{estimatedBudget.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}</strong>
                    </p>
                  </div>
                )}
              </div>

              {/* Block Button */}
              <Button
                onClick={handleBlockBudget}
                disabled={
                  blockingBudget || 
                  !amountToBlock || 
                  parseFloat(amountToBlock) <= 0 || 
                  parseFloat(amountToBlock) > fetchedAmount ||
                  (estimatedBudget > 0 && Math.abs(parseFloat(amountToBlock) - estimatedBudget) > 0.01)
                }
                className="w-full bg-[#2d4a3e] hover:bg-[#1f3329]"
              >
                <Target className="w-4 h-4 mr-2" />
                {blockingBudget ? 'Blocking in SAP...' : 'Block IO in SAP'}
              </Button>
            </>
          )}
        </CardContent>
      </Card>

      {/* IO Blocked Details Card */}
      <Card>
        <CardHeader>
          <CardTitle className="flex items-center gap-2">
            <CircleCheckBig className="w-5 h-5 text-green-600" />
            IO Blocked Details
          </CardTitle>
          <CardDescription>
            Details of IO blocked in SAP system
          </CardDescription>
        </CardHeader>
        <CardContent>
          {blockedDetails ? (
            <div className="space-y-4">
              {/* Success Banner */}
              <div className="bg-green-50 border-2 border-green-500 rounded-lg p-4">
                <div className="flex items-start gap-3">
                  <CircleCheckBig className="w-6 h-6 text-green-600 flex-shrink-0 mt-0.5" />
                  <div>
                    <p className="font-semibold text-green-900">IO Blocked Successfully</p>
                    <p className="text-sm text-green-700 mt-1">Budget has been reserved in SAP system</p>
                  </div>
                </div>
              </div>

              {/* Blocked Details */}
              <div className="border rounded-lg divide-y">
                <div className="p-4">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">IO Number</p>
                  <p className="text-sm font-semibold text-gray-900">{blockedDetails.ioNumber}</p>
                </div>
                <div className="p-4">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">SAP Document Number</p>
                  <p className="text-sm font-semibold text-gray-900">{blockedDetails.sapDocumentNumber || 'N/A'}</p>
                </div>
                <div className="p-4 bg-green-50">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">Blocked Amount</p>
                  <p className="text-xl font-bold text-green-700">
                    ₹{blockedDetails.blockedAmount.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                  </p>
                </div>
                <div className="p-4">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">Available Amount (Before Block)</p>
                  <p className="text-sm font-medium text-gray-900">
                    ₹{blockedDetails.availableBalance.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                  </p>
                </div>
                <div className="p-4 bg-blue-50">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">Remaining Amount (After Block)</p>
                  <p className="text-sm font-bold text-blue-700">
                    ₹{blockedDetails.remainingBalance.toLocaleString('en-IN', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}
                  </p>
                </div>
                <div className="p-4">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">Blocked By</p>
                  <p className="text-sm font-medium text-gray-900">{blockedDetails.blockedBy}</p>
                </div>
                <div className="p-4">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">Blocked At</p>
                  <p className="text-sm font-medium text-gray-900">
                    {new Date(blockedDetails.blockedDate).toLocaleString('en-IN', {
                      year: 'numeric',
                      month: 'short',
                      day: 'numeric',
                      hour: 'numeric',
                      minute: 'numeric',
                      hour12: true
                    })}
                  </p>
                </div>
                <div className="p-4 bg-gray-50">
                  <p className="text-xs text-gray-500 uppercase tracking-wide mb-1">Status</p>
                  <Badge className="bg-green-100 text-green-800 border-green-200">
                    <CircleCheckBig className="w-3 h-3 mr-1" />
                    Blocked
                  </Badge>
                </div>
              </div>
            </div>
          ) : (
            <div className="text-center py-12">
              <DollarSign className="w-16 h-16 text-gray-300 mx-auto mb-4" />
              <p className="text-sm text-gray-500 mb-2">No IO blocked yet</p>
              <p className="text-xs text-gray-400">
                Enter IO number and fetch amount to block budget
              </p>
            </div>
          )}
        </CardContent>
      </Card>
    </div>
  );
}
