import React, { useCallback, useMemo, useState } from 'react';
import { ChevronDown, ChevronUp, GripVertical, Loader2, Trash2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';

function newLineRow() {
    return {
        id: `${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,
        product_service: '',
        description: '',
        qty: '1',
        rate: '0',
        billing_interval: 'monthly',
        currency: 'USD',
    };
}

function parseNum(s) {
    const n = parseFloat(String(s ?? '').replace(/,/g, '').trim());
    return Number.isFinite(n) ? n : NaN;
}

function fmtMoneyAmount(n) {
    if (!Number.isFinite(n)) return '—';
    return new Intl.NumberFormat('en-US', {
        style: 'currency',
        currency: 'USD',
        minimumFractionDigits: 2,
        maximumFractionDigits: 2,
    }).format(n);
}

/**
 * Modal to capture PO / customer / line items before marking a deal Won (invoicing).
 * @param {boolean | undefined} gmailInvitesReady — from /api/auth/me; false blocks submit until user reconnects Gmail.
 */
export default function WonBillingModal({ dealName, busy, onCancel, onSubmit, gmailInvitesReady }) {
    const [poNumber, setPoNumber] = useState('');
    const [customerLegalName, setCustomerLegalName] = useState('');
    const [customerAddress, setCustomerAddress] = useState('');
    const [contactPersonName, setContactPersonName] = useState('');
    const [channelPartnerName, setChannelPartnerName] = useState('');
    const [noteToCustomer, setNoteToCustomer] = useState('');
    const [noteToAccounts, setNoteToAccounts] = useState('');
    const [lines, setLines] = useState(() => [newLineRow()]);
    const [localError, setLocalError] = useState('');

    const lineAmounts = useMemo(() => {
        return lines.map((row) => {
            const q = parseNum(row.qty);
            const r = parseNum(row.rate);
            if (!Number.isFinite(q) || !Number.isFinite(r)) return NaN;
            return Math.round(q * r * 100) / 100;
        });
    }, [lines]);

    const subtotal = useMemo(() => {
        return lineAmounts.reduce((a, v) => a + (Number.isFinite(v) ? v : 0), 0);
    }, [lineAmounts]);

    const updateLine = useCallback((id, patch) => {
        setLines((prev) => prev.map((row) => (row.id === id ? { ...row, ...patch } : row)));
    }, []);

    const removeLine = useCallback((id) => {
        setLines((prev) => (prev.length <= 1 ? prev : prev.filter((r) => r.id !== id)));
    }, []);

    const addLine = useCallback(() => {
        setLines((prev) => [...prev, newLineRow()]);
    }, []);

    const clearAllLines = useCallback(() => {
        setLines([newLineRow()]);
    }, []);

    const moveLine = useCallback((index, dir) => {
        setLines((prev) => {
            const j = index + dir;
            if (j < 0 || j >= prev.length) return prev;
            const next = [...prev];
            const t = next[index];
            next[index] = next[j];
            next[j] = t;
            return next;
        });
    }, []);

    const handleSubmit = () => {
        setLocalError('');
        if (gmailInvitesReady === false) {
            setLocalError('Connect Gmail below before marking this deal won.');
            return;
        }
        if (!poNumber.trim()) {
            setLocalError('PO number is required.');
            return;
        }
        if (!customerLegalName.trim()) {
            setLocalError('Customer legal name is required.');
            return;
        }
        if (!customerAddress.trim()) {
            setLocalError('Customer address is required.');
            return;
        }
        if (!contactPersonName.trim()) {
            setLocalError('Contact person name is required.');
            return;
        }
        if (!noteToAccounts.trim()) {
            setLocalError('Note to our accounts is required.');
            return;
        }
        const items = [];
        for (const row of lines) {
            const ps = row.product_service.trim();
            if (!ps) {
                setLocalError('Each line must have a product or service name.');
                return;
            }
            if (!row.description.trim()) {
                setLocalError('Each line must have a description.');
                return;
            }
            if (!row.billing_interval) {
                setLocalError('Each line must have a billing interval.');
                return;
            }
            if (!row.currency) {
                setLocalError('Each line must have a currency.');
                return;
            }
            const q = parseNum(row.qty);
            const r = parseNum(row.rate);
            if (!Number.isFinite(q) || q <= 0) {
                setLocalError('Each line needs a valid quantity greater than 0.');
                return;
            }
            if (!Number.isFinite(r) || r < 0) {
                setLocalError('Each line needs a valid rate (0 or greater).');
                return;
            }
            items.push({
                product_service: ps,
                description: row.description.trim(),
                qty: q,
                rate: r,
                billing_interval: row.billing_interval || 'monthly',
                currency: row.currency || 'USD',
            });
        }
        onSubmit({
            po_number: poNumber.trim(),
            customer_legal_name: customerLegalName.trim(),
            customer_address: customerAddress.trim(),
            contact_person_name: contactPersonName.trim(),
            channel_partner_name: channelPartnerName.trim() || null,
            note_to_customer: noteToCustomer.trim(),
            note_to_accounts: noteToAccounts.trim(),
            line_items: items,
        });
    };

    return (
        <div
            className="fixed inset-0 z-[70] flex items-center justify-center bg-black/40 p-4"
            role="dialog"
            aria-modal="true"
            aria-labelledby="won-billing-title"
            onClick={() => {
                if (!busy) onCancel();
            }}
        >
            <div
                className="max-h-[min(92vh,900px)] w-full max-w-4xl overflow-y-auto rounded-xl border border-slate-200 bg-white p-6 shadow-xl"
                onClick={(e) => e.stopPropagation()}
            >
                <h3 id="won-billing-title" className="text-lg font-semibold text-slate-900">
                    Mark deal as won — billing & PO
                </h3>
                <p className="mt-1 text-sm text-slate-600">
                    {dealName ? (
                        <>
                            <span className="font-medium text-slate-800">{dealName}</span>
                            <span> — complete the details below for accurate invoicing.</span>
                        </>
                    ) : (
                        'Complete the details below for accurate invoicing.'
                    )}
                </p>
                <div
                    className="mt-3 rounded-lg border border-amber-200 bg-amber-50 px-3 py-2 text-xs text-amber-950"
                    role="note"
                >
                    Please double-check every field and line item so amounts, names, and PO match your customer
                    agreement. Errors here can cause invoice mistakes.
                </div>

                {gmailInvitesReady === false ? (
                    <p className="mt-3 text-xs text-amber-900 bg-amber-50 border border-amber-200 rounded-lg px-3 py-2">
                        Workspace admins get an email when you mark a deal won. Sign in with Google again (consent
                        screen) or use{' '}
                        <a
                            href="/api/auth/google?reauth_gmail=1"
                            className="font-medium text-violet-700 underline"
                        >
                            Reconnect Google for invites
                        </a>
                        , then return here and submit again.
                    </p>
                ) : null}

                <div className="mt-5 grid grid-cols-1 gap-3 sm:grid-cols-2">
                    <div>
                        <label className="mb-1 block text-xs font-medium text-slate-600">
                            PO number <span className="text-red-600">*</span>
                        </label>
                        <Input value={poNumber} onChange={(e) => setPoNumber(e.target.value)} className="bg-white" />
                    </div>
                    <div>
                        <label className="mb-1 block text-xs font-medium text-slate-600">
                            Customer legal name <span className="text-red-600">*</span>
                        </label>
                        <Input
                            value={customerLegalName}
                            onChange={(e) => setCustomerLegalName(e.target.value)}
                            className="bg-white"
                        />
                    </div>
                    <div className="sm:col-span-2">
                        <label className="mb-1 block text-xs font-medium text-slate-600">
                            Customer address <span className="text-red-600">*</span>
                        </label>
                        <Textarea
                            value={customerAddress}
                            onChange={(e) => setCustomerAddress(e.target.value)}
                            className="min-h-[72px] bg-white text-sm"
                            rows={3}
                        />
                    </div>
                    <div>
                        <label className="mb-1 block text-xs font-medium text-slate-600">
                            Contact person name <span className="text-red-600">*</span>
                        </label>
                        <Input
                            value={contactPersonName}
                            onChange={(e) => setContactPersonName(e.target.value)}
                            className="bg-white"
                        />
                    </div>
                    <div>
                        <label className="mb-1 block text-xs font-medium text-slate-600">
                            Channel partner name (if any)
                        </label>
                        <Input
                            value={channelPartnerName}
                            onChange={(e) => setChannelPartnerName(e.target.value)}
                            className="bg-white"
                            placeholder="Optional"
                        />
                    </div>
                    <div className="sm:col-span-2">
                        <label className="mb-1 block text-xs font-medium text-slate-600">Note to customer</label>
                        <Textarea
                            value={noteToCustomer}
                            onChange={(e) => setNoteToCustomer(e.target.value)}
                            className="min-h-[64px] bg-white text-sm"
                            rows={2}
                        />
                    </div>
                    <div className="sm:col-span-2">
                        <label className="mb-1 block text-xs font-medium text-slate-600">
                            Note to our accounts <span className="text-red-600">*</span>
                        </label>
                        <Textarea
                            value={noteToAccounts}
                            onChange={(e) => setNoteToAccounts(e.target.value)}
                            className="min-h-[64px] bg-white text-sm"
                            rows={2}
                        />
                    </div>
                </div>

                <div className="mt-6">
                    <div className="mb-2 flex flex-wrap items-center justify-between gap-2">
                        <span className="text-sm font-semibold text-slate-800">Products / services</span>
                        <div className="flex flex-wrap gap-2">
                            <Button type="button" variant="outline" size="sm" className="h-8" onClick={addLine}>
                                + Add line
                            </Button>
                            <Button type="button" variant="ghost" size="sm" className="h-8 text-slate-600" onClick={clearAllLines}>
                                Clear all lines
                            </Button>
                        </div>
                    </div>
                    <div className="overflow-x-auto rounded-lg border border-slate-200">
                        <table className="w-full min-w-[960px] border-collapse text-sm">
                            <thead>
                                <tr className="border-b border-slate-200 bg-slate-50 text-left text-xs font-semibold text-slate-600">
                                    <th className="w-8 px-1 py-2" aria-hidden />
                                    <th className="w-8 px-1 py-2 text-center">#</th>
                                    <th className="min-w-[140px] px-2 py-2">Product / service</th>
                                    <th className="min-w-[120px] px-2 py-2">
                                        Description <span className="text-red-600">*</span>
                                    </th>
                                    <th className="min-w-[130px] px-2 py-2">
                                        Billing interval <span className="text-red-600">*</span>
                                    </th>
                                    <th className="w-24 px-2 py-2">
                                        Currency <span className="text-red-600">*</span>
                                    </th>
                                    <th className="w-20 px-2 py-2 text-right">Qty</th>
                                    <th className="w-24 px-2 py-2 text-right">Rate</th>
                                    <th className="w-28 px-2 py-2 text-right">Amount</th>
                                    <th className="w-10 px-1 py-2" aria-hidden />
                                </tr>
                            </thead>
                            <tbody>
                                {lines.map((row, idx) => {
                                    const amt = lineAmounts[idx];
                                    return (
                                        <tr key={row.id} className="border-b border-slate-100">
                                            <td className="align-middle px-1 py-1">
                                                <div className="flex flex-col items-center gap-0.5">
                                                    <GripVertical className="h-4 w-4 text-slate-300" aria-hidden />
                                                    <Button
                                                        type="button"
                                                        variant="ghost"
                                                        size="icon"
                                                        className="h-6 w-6 shrink-0"
                                                        disabled={idx === 0}
                                                        onClick={() => moveLine(idx, -1)}
                                                        aria-label="Move line up"
                                                    >
                                                        <ChevronUp className="h-3.5 w-3.5" />
                                                    </Button>
                                                    <Button
                                                        type="button"
                                                        variant="ghost"
                                                        size="icon"
                                                        className="h-6 w-6 shrink-0"
                                                        disabled={idx === lines.length - 1}
                                                        onClick={() => moveLine(idx, 1)}
                                                        aria-label="Move line down"
                                                    >
                                                        <ChevronDown className="h-3.5 w-3.5" />
                                                    </Button>
                                                </div>
                                            </td>
                                            <td className="px-1 py-2 text-center text-xs text-slate-500 tabular-nums">
                                                {idx + 1}
                                            </td>
                                            <td className="px-2 py-1">
                                                <Input
                                                    value={row.product_service}
                                                    onChange={(e) =>
                                                        updateLine(row.id, { product_service: e.target.value })
                                                    }
                                                    className="h-8 bg-white text-xs"
                                                    placeholder="Product or service"
                                                />
                                            </td>
                                            <td className="px-2 py-1">
                                                <Input
                                                    value={row.description}
                                                    onChange={(e) =>
                                                        updateLine(row.id, { description: e.target.value })
                                                    }
                                                    className="h-8 bg-white text-xs"
                                                    placeholder="Description"
                                                />
                                            </td>
                                            <td className="px-2 py-1">
                                                <Select
                                                    value={row.billing_interval || 'monthly'}
                                                    onValueChange={(v) =>
                                                        updateLine(row.id, { billing_interval: v })
                                                    }
                                                >
                                                    <SelectTrigger className="h-8 bg-white text-xs">
                                                        <span className="truncate">
                                                            {row.billing_interval === 'one_time'
                                                                ? 'One-time'
                                                                : row.billing_interval === 'quarterly'
                                                                  ? 'Every 3 mo'
                                                                  : row.billing_interval === 'annual'
                                                                    ? 'Every year'
                                                                    : 'Every month'}
                                                        </span>
                                                    </SelectTrigger>
                                                    <SelectContent>
                                                        <SelectItem value="monthly">Every month</SelectItem>
                                                        <SelectItem value="quarterly">Every 3 months</SelectItem>
                                                        <SelectItem value="annual">Every year</SelectItem>
                                                        <SelectItem value="one_time">One-time</SelectItem>
                                                    </SelectContent>
                                                </Select>
                                            </td>
                                            <td className="px-2 py-1">
                                                <Select
                                                    value={row.currency || 'USD'}
                                                    onValueChange={(v) =>
                                                        updateLine(row.id, { currency: v })
                                                    }
                                                >
                                                    <SelectTrigger className="h-8 bg-white text-xs">
                                                        {row.currency || 'USD'}
                                                    </SelectTrigger>
                                                    <SelectContent>
                                                        <SelectItem value="USD">USD</SelectItem>
                                                        <SelectItem value="CAD">CAD</SelectItem>
                                                    </SelectContent>
                                                </Select>
                                            </td>
                                            <td className="px-2 py-1">
                                                <Input
                                                    value={row.qty}
                                                    onChange={(e) => updateLine(row.id, { qty: e.target.value })}
                                                    className="h-8 bg-white text-right text-xs tabular-nums"
                                                    inputMode="decimal"
                                                />
                                            </td>
                                            <td className="px-2 py-1">
                                                <Input
                                                    value={row.rate}
                                                    onChange={(e) => updateLine(row.id, { rate: e.target.value })}
                                                    className="h-8 bg-white text-right text-xs tabular-nums"
                                                    inputMode="decimal"
                                                />
                                            </td>
                                            <td className="px-2 py-2 text-right text-xs font-medium tabular-nums text-slate-800">
                                                {fmtMoneyAmount(amt)}
                                            </td>
                                            <td className="px-1 py-1 text-center">
                                                <Button
                                                    type="button"
                                                    variant="ghost"
                                                    size="icon"
                                                    className="h-8 w-8 text-slate-500 hover:text-red-600"
                                                    disabled={lines.length <= 1}
                                                    onClick={() => removeLine(row.id)}
                                                    aria-label="Remove line"
                                                >
                                                    <Trash2 className="h-4 w-4" />
                                                </Button>
                                            </td>
                                        </tr>
                                    );
                                })}
                            </tbody>
                        </table>
                    </div>
                    <div className="mt-3 flex justify-end border-t border-slate-100 pt-2">
                        <div className="text-sm">
                            <span className="text-slate-500">Subtotal </span>
                            <span className="font-semibold tabular-nums text-slate-900">{fmtMoneyAmount(subtotal)}</span>
                        </div>
                    </div>
                </div>

                {localError ? (
                    <p className="mt-3 text-sm text-red-600" role="alert">
                        {localError}
                    </p>
                ) : null}

                <div className="mt-6 flex flex-wrap justify-end gap-2">
                    <Button type="button" variant="outline" onClick={onCancel} disabled={busy}>
                        Cancel
                    </Button>
                    <Button
                        type="button"
                        className="bg-emerald-600 hover:bg-emerald-700"
                        onClick={handleSubmit}
                        disabled={busy || gmailInvitesReady === false}
                    >
                        {busy ? (
                            <>
                                <Loader2 className="mr-2 h-4 w-4 animate-spin" aria-hidden />
                                Saving…
                            </>
                        ) : (
                            'Submit & mark won'
                        )}
                    </Button>
                </div>
            </div>
        </div>
    );
}
