import { useState, useEffect, useCallback } from "react";
import { Modal, Button, Form, Table, Alert } from "react-bootstrap";
import { generateQr, LunchChoice, LocationLunchChoicesMap, RestaurantDayMenu, QrRecipient } from "../../../../types";
import { parsePriceCzk } from "../../utils/parsePrice";

type DinerEntry = {
    login: string;
    selectedFoods: number[];
    baseAmount: number;
    baseAmountParseFailed: boolean;
    surchargeText: string;
    surchargeAmount: string;
    included: boolean;
};

type Props = {
    isOpen: boolean;
    onClose: () => void;
    locationKey: LunchChoice;
    locationName: string;
    locationChoices: LocationLunchChoicesMap;
    menu: RestaurantDayMenu | undefined;
    payerLogin: string;
    bankAccount: string;
    bankAccountHolder: string;
};

function sanitizeAmount(value: string): string {
    return value.replace(/[^0-9.,]/g, '').replace(',', '.');
}

function parseAmount(s: string): number | null {
    if (!s || s.trim().length === 0) return null;
    const n = parseFloat(s);
    if (isNaN(n) || n < 0) return null;
    const parts = s.split('.');
    if (parts.length === 2 && parts[1].length > 2) return null;
    return Math.round(n * 100) / 100;
}

export default function PayForAllModal({ isOpen, onClose, locationName, locationChoices, menu, payerLogin, bankAccount, bankAccountHolder }: Readonly<Props>) {
    const [diners, setDiners] = useState<DinerEntry[]>([]);
    const [tipTotal, setTipTotal] = useState('');
    const [error, setError] = useState<string | null>(null);
    const [loading, setLoading] = useState(false);
    const [success, setSuccess] = useState(false);

    const hasMenu = !!menu;

    useEffect(() => {
        if (!isOpen) return;
        const entries: DinerEntry[] = Object.entries(locationChoices).map(([login, choice]) => {
            const selectedFoods = choice.selectedFoods ?? [];
            let baseAmount = 0;
            let baseAmountParseFailed = false;
            if (menu) {
                for (const idx of selectedFoods) {
                    const price = parsePriceCzk(menu.food?.[idx]?.price);
                    if (price === null) {
                        baseAmountParseFailed = true;
                    } else {
                        baseAmount += price;
                    }
                }
            }
            return {
                login,
                selectedFoods,
                baseAmount,
                baseAmountParseFailed,
                surchargeText: '',
                surchargeAmount: '',
                included: login !== payerLogin,
            };
        });
        setDiners(entries);
        setTipTotal('');
        setError(null);
        setSuccess(false);
    }, [isOpen, locationChoices, menu, payerLogin]);

    const includedDiners = diners.filter(d => d.included && d.login !== payerLogin);
    const tipPerPerson = (() => {
        if (includedDiners.length === 0) return 0;
        const tip = parseAmount(tipTotal);
        if (tip === null || tip === 0) return 0;
        return Math.round((tip / includedDiners.length) * 100) / 100;
    })();

    const getTotal = (d: DinerEntry): number => {
        const surcharge = parseAmount(d.surchargeAmount) ?? 0;
        const tip = d.included && d.login !== payerLogin ? tipPerPerson : 0;
        return Math.round((d.baseAmount + surcharge + tip) * 100) / 100;
    };

    const handleInclude = useCallback((login: string, checked: boolean) => {
        setDiners(prev => prev.map(d => d.login === login ? { ...d, included: checked } : d));
    }, []);

    const handleSurchargeText = useCallback((login: string, value: string) => {
        setDiners(prev => prev.map(d => d.login === login ? { ...d, surchargeText: value } : d));
    }, []);

    const handleSurchargeAmount = useCallback((login: string, value: string) => {
        setDiners(prev => prev.map(d => d.login === login ? { ...d, surchargeAmount: sanitizeAmount(value) } : d));
    }, []);

    const handleGenerate = async () => {
        setError(null);
        const recipients: QrRecipient[] = [];

        for (const d of diners) {
            if (!d.included || d.login === payerLogin) continue;
            const total = getTotal(d);
            if (total <= 0) {
                setError(`Celková částka pro ${d.login} musí být kladná`);
                return;
            }
            const amountStr = total.toString();
            if (amountStr.includes('.') && amountStr.split('.')[1].length > 2) {
                setError(`Částka pro ${d.login} má více než 2 desetinná místa`);
                return;
            }
            const foods = d.selectedFoods.map(i => menu?.food?.[i]?.name).filter(Boolean).join(', ');
            const purposeBase = `Oběd ${locationName}${foods ? ` — ${foods}` : ''}`;
            recipients.push({
                login: d.login,
                purpose: purposeBase.substring(0, 60),
                amount: total,
            });
        }

        if (recipients.length === 0) {
            setError("Nebyl vybrán žádný příjemce");
            return;
        }

        setLoading(true);
        try {
            const response = await generateQr({
                body: { recipients, bankAccount, bankAccountHolder },
            });
            if (response.error) {
                setError((response.error as any).error || 'Nastala chyba při generování QR kódů');
            } else {
                setSuccess(true);
                setTimeout(() => onClose(), 2000);
            }
        } catch (e: any) {
            setError(e.message || 'Nastala chyba při generování QR kódů');
        } finally {
            setLoading(false);
        }
    };

    const anyParseFailed = diners.some(d => d.baseAmountParseFailed && d.included);

    return (
        <Modal show={isOpen} onHide={onClose} size="lg">
            <Modal.Header closeButton>
                <Modal.Title><h2>Zaplatit za všechny — {locationName}</h2></Modal.Title>
            </Modal.Header>
            <Modal.Body>
                {success ? (
                    <Alert variant="success">
                        QR kódy byly úspěšně vygenerovány! Uživatelé je uvidí v sekci „Nevyřízené platby".
                    </Alert>
                ) : (
                    <>
                        <p>Zaplatili jste za skupinu v restauraci. Nastavte příplatky a dýško, poté vygenerujte QR kódy pro ostatní.</p>

                        {!hasMenu && (
                            <Alert variant="info">
                                Pro tuto skupinu nejsou k dispozici ceny jídel — vyplňte příplatky ručně.
                            </Alert>
                        )}

                        {anyParseFailed && (
                            <Alert variant="warning">
                                U některých jídel se nepodařilo načíst cenu — doplňte ji ručně v sloupci Příplatek.
                            </Alert>
                        )}

                        {error && (
                            <Alert variant="danger" onClose={() => setError(null)} dismissible>
                                {error}
                            </Alert>
                        )}

                        <Table striped bordered hover responsive size="sm">
                            <thead>
                                <tr>
                                    <th style={{ width: 40 }}></th>
                                    <th>Strávník</th>
                                    <th>Jídla</th>
                                    <th style={{ width: 220 }}>Příplatek</th>
                                    <th style={{ width: 90 }}>Dýško</th>
                                    <th style={{ width: 90 }}>Celkem</th>
                                </tr>
                            </thead>
                            <tbody>
                                {diners.map(d => {
                                    const isPayer = d.login === payerLogin;
                                    const foodNames = d.selectedFoods.map(i => menu?.food?.[i]?.name).filter(Boolean).join(', ');
                                    const total = getTotal(d);
                                    return (
                                        <tr key={d.login} className={!d.included && !isPayer ? 'text-muted' : ''}>
                                            <td className="text-center">
                                                {isPayer ? (
                                                    <small className="text-muted">plátce</small>
                                                ) : (
                                                    <Form.Check
                                                        type="checkbox"
                                                        checked={d.included}
                                                        onChange={e => handleInclude(d.login, e.target.checked)}
                                                    />
                                                )}
                                            </td>
                                            <td><strong>{d.login}</strong></td>
                                            <td>
                                                <small>
                                                    {foodNames || <span className="text-muted">—</span>}
                                                    {hasMenu && d.baseAmount > 0 && <span className="text-muted"> ({d.baseAmount} Kč)</span>}
                                                    {d.baseAmountParseFailed && <span className="text-warning"> ⚠</span>}
                                                </small>
                                            </td>
                                            <td>
                                                {!isPayer && (
                                                    <div className="d-flex gap-1">
                                                        <Form.Control
                                                            type="text"
                                                            placeholder="popis"
                                                            value={d.surchargeText}
                                                            onChange={e => handleSurchargeText(d.login, e.target.value)}
                                                            disabled={!d.included}
                                                            size="sm"
                                                            onKeyDown={e => e.stopPropagation()}
                                                        />
                                                        <Form.Control
                                                            type="text"
                                                            placeholder="Kč"
                                                            value={d.surchargeAmount}
                                                            onChange={e => handleSurchargeAmount(d.login, e.target.value)}
                                                            disabled={!d.included}
                                                            size="sm"
                                                            style={{ width: 70 }}
                                                            onKeyDown={e => e.stopPropagation()}
                                                        />
                                                    </div>
                                                )}
                                            </td>
                                            <td className="text-end">
                                                {!isPayer && d.included ? `${tipPerPerson} Kč` : '—'}
                                            </td>
                                            <td className="text-end fw-bold">
                                                {!isPayer ? `${total} Kč` : '—'}
                                            </td>
                                        </tr>
                                    );
                                })}
                            </tbody>
                        </Table>

                        <div className="d-flex align-items-center gap-2 mt-2">
                            <label className="mb-0 text-nowrap">Dýško celkem (Kč):</label>
                            <Form.Control
                                type="text"
                                placeholder="0"
                                value={tipTotal}
                                onChange={e => setTipTotal(sanitizeAmount(e.target.value))}
                                size="sm"
                                style={{ width: 100 }}
                                onKeyDown={e => e.stopPropagation()}
                            />
                            <small className="text-muted">
                                {includedDiners.length > 0 && tipPerPerson > 0
                                    ? `(${tipPerPerson} Kč / osoba)`
                                    : ''}
                            </small>
                        </div>
                    </>
                )}
            </Modal.Body>
            <Modal.Footer>
                {!success && (
                    <>
                        <span className="me-auto text-muted">
                            Příjemci: {includedDiners.length}
                        </span>
                        <Button variant="secondary" onClick={onClose} disabled={loading}>
                            Storno
                        </Button>
                        <Button
                            variant="primary"
                            onClick={handleGenerate}
                            disabled={loading || includedDiners.length === 0}
                        >
                            {loading ? 'Generuji...' : 'Vygenerovat QR'}
                        </Button>
                    </>
                )}
                {success && (
                    <Button variant="secondary" onClick={onClose}>Zavřít</Button>
                )}
            </Modal.Footer>
        </Modal>
    );
}
