import { useState } from 'react';
import { router } from '@inertiajs/react';
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
import { Button } from '@/components/ui/button';

interface Allocation {
    bucket_id: string;
    bucket_name: string;
    bucket_type: 'need' | 'want' | 'overflow';
    allocated_amount: number;
    remaining_capacity: number | null;
}

interface PreviewResult {
    allocations: Allocation[];
    total_allocated: number;
    unallocated: number;
}

interface IncomeDistributionPreviewProps {
    scenarioId: string;
}

const bucketTypeColor = {
    need: 'bg-blue-100 text-blue-800',
    want: 'bg-green-100 text-green-800',
    overflow: 'bg-amber-100 text-amber-800',
} as const;

const csrfToken = () =>
    document.querySelector('meta[name="csrf-token"]')?.getAttribute('content') || '';

export default function IncomeDistributionPreview({ scenarioId }: IncomeDistributionPreviewProps) {
    const [amount, setAmount] = useState('');
    const [preview, setPreview] = useState<PreviewResult | null>(null);
    const [isLoading, setIsLoading] = useState(false);
    const [isApplying, setIsApplying] = useState(false);
    const [error, setError] = useState<string | null>(null);
    const [applied, setApplied] = useState(false);

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setIsLoading(true);
        setError(null);
        setApplied(false);

        const parsed = parseFloat(amount);
        if (isNaN(parsed) || parsed <= 0) {
            setError('Please enter a valid amount');
            setIsLoading(false);
            return;
        }

        try {
            const response = await fetch(`/scenarios/${scenarioId}/projections/preview`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': csrfToken(),
                },
                body: JSON.stringify({ amount: Math.round(parsed * 100) }),
            });

            if (!response.ok) {
                let message = 'Failed to preview allocation';
                try {
                    const data = await response.json();
                    message = data.message || message;
                } catch { /* non-JSON error body */ }
                setError(message);
                setPreview(null);
                return;
            }

            const data: PreviewResult = await response.json();
            setPreview(data);
        } catch {
            setError('Failed to connect to server');
            setPreview(null);
        } finally {
            setIsLoading(false);
        }
    };

    const handleApply = async () => {
        const parsed = parseFloat(amount);
        if (isNaN(parsed) || parsed <= 0) return;

        setIsApplying(true);
        setError(null);

        try {
            const response = await fetch(`/scenarios/${scenarioId}/projections/apply`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                    'X-CSRF-TOKEN': csrfToken(),
                },
                body: JSON.stringify({ amount: Math.round(parsed * 100) }),
            });

            if (!response.ok) {
                let message = 'Failed to save distribution';
                try {
                    const data = await response.json();
                    message = data.message || message;
                } catch { /* non-JSON error body */ }
                setError(message);
                return;
            }

            setPreview(null);
            setAmount('');
            setApplied(true);
            router.reload({ only: ['buckets'] });
        } catch {
            setError('Failed to connect to server');
        } finally {
            setIsApplying(false);
        }
    };

    return (
        <Card>
            <CardHeader>
                <CardTitle>Income Distribution Preview</CardTitle>
            </CardHeader>
            <CardContent>
                <form onSubmit={handleSubmit} className="flex gap-3 items-end">
                    <div className="flex-1">
                        <label htmlFor="preview-amount" className="block text-sm font-medium text-gray-700 mb-1">
                            Income Amount ($)
                        </label>
                        <input
                            type="number"
                            id="preview-amount"
                            value={amount}
                            onChange={(e) => setAmount(e.target.value)}
                            className="block w-full rounded-md border-gray-300 shadow-sm focus:border-blue-500 focus:ring-blue-500 text-gray-900"
                            placeholder="e.g., 3000"
                            step="0.01"
                            min="0.01"
                            required
                        />
                    </div>
                    <Button type="submit" disabled={isLoading || isApplying}>
                        {isLoading ? 'Loading...' : 'Preview Distribution'}
                    </Button>
                </form>

                {error && (
                    <div className="mt-4 rounded-md bg-red-50 p-3 text-sm text-red-700">
                        {error}
                    </div>
                )}

                {applied && (
                    <div className="mt-4 rounded-md bg-green-50 p-3 text-sm text-green-700">
                        Distribution saved successfully. Bucket balances have been updated.
                    </div>
                )}

                {preview && (
                    <div className="mt-6 space-y-4">
                        {preview.allocations.length > 0 ? (
                            <div className="divide-y divide-gray-200 rounded-md border border-gray-200">
                                {preview.allocations.map((allocation) => (
                                    <div key={allocation.bucket_id} className="flex items-center justify-between px-4 py-3">
                                        <div className="flex items-center gap-2">
                                            <span className={`inline-flex rounded-full px-2 py-0.5 text-xs font-semibold ${bucketTypeColor[allocation.bucket_type]}`}>
                                                {allocation.bucket_type}
                                            </span>
                                            <span className="font-medium text-gray-900">{allocation.bucket_name}</span>
                                        </div>
                                        <div className="text-right">
                                            <span className="font-semibold text-gray-900">
                                                ${(allocation.allocated_amount / 100).toFixed(2)}
                                            </span>
                                            {allocation.remaining_capacity !== null && (
                                                <span className="ml-2 text-sm text-gray-500">
                                                    (${(allocation.remaining_capacity / 100).toFixed(2)} remaining)
                                                </span>
                                            )}
                                        </div>
                                    </div>
                                ))}
                            </div>
                        ) : (
                            <p className="text-sm text-gray-500">No buckets to allocate to.</p>
                        )}

                        <div className="flex justify-between rounded-md bg-gray-50 px-4 py-3 text-sm font-medium">
                            <span className="text-gray-700">Total Allocated</span>
                            <span className="text-gray-900">${(preview.total_allocated / 100).toFixed(2)}</span>
                        </div>

                        {preview.unallocated > 0 && (
                            <div className="flex justify-between rounded-md bg-amber-50 px-4 py-3 text-sm font-medium">
                                <span className="text-amber-700">Unallocated</span>
                                <span className="text-amber-900">${(preview.unallocated / 100).toFixed(2)}</span>
                            </div>
                        )}

                        {preview.allocations.length > 0 && (
                            <Button
                                onClick={handleApply}
                                disabled={isApplying}
                                className="w-full"
                            >
                                {isApplying ? 'Saving...' : 'Save Distribution'}
                            </Button>
                        )}
                    </div>
                )}
            </CardContent>
        </Card>
    );
}
