"use client";

import React, { useEffect, useMemo, useState } from "react";
import { MdSwapVert, MdAdd, MdDelete } from "react-icons/md";
import { FiX } from "react-icons/fi";
import toast from "react-hot-toast";
import { stockAdjustmentsService, purchaseOrderService } from "@/services/api";
import {
    StockAdjustmentType,
    STOCK_ADJUSTMENT_TYPE_LABELS,
} from "@/types/stock-adjustment";

interface Warehouse {
    id: number;
    name: string;
}

interface Product {
    id: number;
    name: string;
}

interface Line {
    productId: number | "";
    quantityChange: number | "";
}

interface Props {
    isOpen: boolean;
    onClose: () => void;
    onSaved: () => void;
}

const initialLine: Line = { productId: "", quantityChange: "" };

const NewStockAdjustmentModal: React.FC<Props> = ({
    isOpen,
    onClose,
    onSaved,
}) => {
    const [warehouses, setWarehouses] = useState<Warehouse[]>([]);
    const [products, setProducts] = useState<Product[]>([]);
    const [warehouseId, setWarehouseId] = useState<number | "">("");
    const [adjustmentType, setAdjustmentType] = useState<
        StockAdjustmentType | ""
    >("");
    const [reason, setReason] = useState("");
    const [lines, setLines] = useState<Line[]>([{ ...initialLine }]);
    const [isSubmitting, setIsSubmitting] = useState(false);

    useEffect(() => {
        if (!isOpen) return;
        // Reset form on open
        setWarehouseId("");
        setAdjustmentType("");
        setReason("");
        setLines([{ ...initialLine }]);

        // Fetch lookups (only once per open)
        Promise.all([
            purchaseOrderService.getAllWarehouses(),
            purchaseOrderService.getAllProducts(),
        ])
            .then(([wRes, pRes]) => {
                setWarehouses(wRes.data || []);
                setProducts(pRes.data || []);
            })
            .catch(() => {
                toast.error("Failed to load warehouses / products");
            });
    }, [isOpen]);

    const productOptions = useMemo(
        () => products.slice().sort((a, b) => a.name.localeCompare(b.name)),
        [products]
    );

    const addLine = () => setLines((prev) => [...prev, { ...initialLine }]);
    const removeLine = (index: number) =>
        setLines((prev) =>
            prev.length > 1 ? prev.filter((_, i) => i !== index) : prev
        );
    const updateLine = (index: number, patch: Partial<Line>) =>
        setLines((prev) =>
            prev.map((l, i) => (i === index ? { ...l, ...patch } : l))
        );

    const validate = (): string | null => {
        if (!warehouseId) return "Pick a warehouse";
        if (!adjustmentType) return "Pick an adjustment type";
        if (!reason.trim()) return "A reason is required";
        if (lines.length === 0) return "Add at least one line";
        const seen = new Set<number>();
        for (let i = 0; i < lines.length; i++) {
            const l = lines[i];
            if (!l.productId) return `Line ${i + 1}: pick a product`;
            const qty = Number(l.quantityChange);
            if (!Number.isInteger(qty)) return `Line ${i + 1}: quantity must be an integer`;
            if (qty === 0) return `Line ${i + 1}: quantity cannot be zero`;
            if (seen.has(l.productId as number)) {
                return `Line ${i + 1}: product appears more than once`;
            }
            seen.add(l.productId as number);
        }
        return null;
    };

    const handleSubmit = async () => {
        const error = validate();
        if (error) {
            toast.error(error);
            return;
        }
        try {
            setIsSubmitting(true);
            const payload = {
                warehouseId: warehouseId as number,
                adjustmentType: adjustmentType as StockAdjustmentType,
                reason: reason.trim(),
                lines: lines.map((l) => ({
                    productId: l.productId as number,
                    quantityChange: Number(l.quantityChange),
                })),
            };
            await stockAdjustmentsService.createBatch(payload);
            toast.success(
                lines.length === 1
                    ? "Adjustment saved."
                    : `${lines.length} adjustments saved.`
            );
            onSaved();
            onClose();
        } catch (err: any) {
            toast.error(
                err.response?.data?.message || "Failed to save stock adjustment."
            );
        } finally {
            setIsSubmitting(false);
        }
    };

    if (!isOpen) return null;

    return (
        <div className="fixed inset-0 z-50 overflow-y-auto">
            <div className="flex min-h-screen items-center justify-center p-4">
                <div
                    className="fixed inset-0 bg-black bg-opacity-30 transition-opacity"
                    onClick={isSubmitting ? undefined : onClose}
                />

                <div className="relative w-full max-w-3xl transform rounded-lg bg-white text-left shadow-xl transition-all flex flex-col max-h-[90vh]">
                    {/* Header */}
                    <div className="px-6 py-4 border-b border-gray-200 flex items-center gap-3 flex-shrink-0">
                        <div className="flex h-10 w-10 items-center justify-center rounded-full bg-blue-100 flex-shrink-0">
                            <MdSwapVert size={22} color="#3997E0" />
                        </div>
                        <div className="flex-1 min-w-0">
                            <h3 className="text-lg font-bold text-[#0F2851] leading-tight">
                                New Stock Adjustment
                            </h3>
                            <p className="text-sm text-gray-500 truncate">
                                Add one or more product adjustments to a warehouse
                            </p>
                        </div>
                        <button
                            type="button"
                            onClick={onClose}
                            disabled={isSubmitting}
                            className="text-gray-400 hover:text-gray-600 transition-colors flex-shrink-0 disabled:opacity-50 disabled:cursor-not-allowed"
                            title="Close"
                        >
                            <FiX size={24} />
                        </button>
                    </div>

                    {/* Body */}
                    <div className="px-6 py-4 overflow-y-auto flex-1">
                        <div className="space-y-5">
                            {/* Warehouse + Type row */}
                            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                                <div>
                                    <label className="block text-sm font-semibold text-[#0F2851] mb-2">
                                        Warehouse
                                    </label>
                                    <select
                                        value={warehouseId}
                                        onChange={(e) =>
                                            setWarehouseId(
                                                e.target.value ? Number(e.target.value) : ""
                                            )
                                        }
                                        className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm text-black focus:outline-none focus:ring-2 focus:ring-[#3997E0]"
                                    >
                                        <option value="">Select warehouse...</option>
                                        {warehouses.map((w) => (
                                            <option key={w.id} value={w.id}>
                                                {w.name}
                                            </option>
                                        ))}
                                    </select>
                                </div>
                                <div>
                                    <label className="block text-sm font-semibold text-[#0F2851] mb-2">
                                        Type <span className="text-red-500">*</span>
                                    </label>
                                    <select
                                        value={adjustmentType}
                                        onChange={(e) =>
                                            setAdjustmentType(
                                                e.target.value as StockAdjustmentType | ""
                                            )
                                        }
                                        className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm text-black focus:outline-none focus:ring-2 focus:ring-[#3997E0]"
                                    >
                                        <option value="">Select type...</option>
                                        {Object.values(StockAdjustmentType).map((t) => (
                                            <option key={t} value={t}>
                                                {STOCK_ADJUSTMENT_TYPE_LABELS[t]}
                                            </option>
                                        ))}
                                    </select>
                                </div>
                            </div>

                            {/* Reason */}
                            <div>
                                <label className="block text-sm font-semibold text-[#0F2851] mb-2">
                                    Reason <span className="text-red-500">*</span>
                                </label>
                                <textarea
                                    value={reason}
                                    onChange={(e) => setReason(e.target.value)}
                                    placeholder="Why is this adjustment being made?"
                                    rows={2}
                                    className="w-full px-3 py-2 border border-gray-300 rounded-md text-sm text-black focus:outline-none focus:ring-2 focus:ring-[#3997E0]"
                                />
                            </div>

                            {/* Lines */}
                            <div>
                                <div className="flex items-center justify-between mb-2">
                                    <label className="block text-sm font-semibold text-[#0F2851]">
                                        Products & Quantities
                                    </label>
                                    <button
                                        type="button"
                                        onClick={addLine}
                                        className="inline-flex items-center gap-1 text-sm text-[#3997E0] hover:underline"
                                    >
                                        <MdAdd size={16} />
                                        Add line
                                    </button>
                                </div>
                                <div className="border border-gray-200 rounded-md overflow-hidden">
                                    <table className="min-w-full divide-y divide-gray-200 text-sm">
                                        <thead className="bg-gray-50">
                                            <tr>
                                                <th className="px-3 py-2 text-left text-xs font-bold text-black uppercase">
                                                    Product
                                                </th>
                                                <th className="px-3 py-2 text-left text-xs font-bold text-black uppercase w-40">
                                                    Quantity
                                                </th>
                                                <th className="px-3 py-2 w-10"></th>
                                            </tr>
                                        </thead>
                                        <tbody className="bg-white divide-y divide-gray-100">
                                            {lines.map((line, i) => {
                                                // Hide products already picked in OTHER rows so a
                                                // product can only appear once per batch. Keep the
                                                // row's own current pick visible so it stays selected.
                                                const takenIds = new Set(
                                                    lines
                                                        .map((l, idx) =>
                                                            idx !== i && l.productId
                                                                ? (l.productId as number)
                                                                : null
                                                        )
                                                        .filter((id): id is number => id !== null)
                                                );
                                                const availableProducts = productOptions.filter(
                                                    (p) => !takenIds.has(p.id)
                                                );

                                                return (
                                                <tr
                                                    key={i}
                                                    className={i % 2 === 0 ? "bg-white" : "bg-[#F2F9FF]"}
                                                >
                                                    <td className="px-3 py-2">
                                                        <select
                                                            value={line.productId}
                                                            onChange={(e) =>
                                                                updateLine(i, {
                                                                    productId: e.target.value
                                                                        ? Number(e.target.value)
                                                                        : "",
                                                                })
                                                            }
                                                            className="w-full px-2 py-1 border border-gray-300 rounded-md text-sm text-black focus:outline-none focus:ring-2 focus:ring-[#3997E0]"
                                                        >
                                                            <option value="">Select product...</option>
                                                            {availableProducts.map((p) => (
                                                                <option key={p.id} value={p.id}>
                                                                    {p.name}
                                                                </option>
                                                            ))}
                                                        </select>
                                                    </td>
                                                    <td className="px-3 py-2">
                                                        <input
                                                            type="number"
                                                            value={line.quantityChange}
                                                            onChange={(e) =>
                                                                updateLine(i, {
                                                                    quantityChange: e.target.value
                                                                        ? Number(e.target.value)
                                                                        : "",
                                                                })
                                                            }
                                                            placeholder="+5 or -3"
                                                            className="w-full px-2 py-1 border border-gray-300 rounded-md text-sm text-black font-mono focus:outline-none focus:ring-2 focus:ring-[#3997E0]"
                                                        />
                                                    </td>
                                                    <td className="px-3 py-2 text-right">
                                                        <button
                                                            type="button"
                                                            onClick={() => removeLine(i)}
                                                            disabled={lines.length === 1}
                                                            className="text-gray-400 hover:text-red-600 disabled:opacity-30 disabled:cursor-not-allowed"
                                                            title="Remove line"
                                                        >
                                                            <MdDelete size={18} />
                                                        </button>
                                                    </td>
                                                </tr>
                                                );
                                            })}
                                        </tbody>
                                    </table>
                                </div>
                                <p className="text-xs text-gray-500 mt-2">
                                    Positive numbers add stock, negative numbers remove it. The
                                    system rejects adjustments that would push a balance below
                                    zero.
                                </p>
                            </div>
                        </div>
                    </div>

                    {/* Footer */}
                    <div className="px-6 py-4 border-t border-gray-200 flex-shrink-0">
                        <div className="flex justify-end gap-3">
                            <button
                                type="button"
                                onClick={onClose}
                                disabled={isSubmitting}
                                className="rounded-xl border border-[#3997E0] bg-white px-6 py-2 text-base font-medium text-[#3997E0] hover:bg-gray-50 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                Cancel
                            </button>
                            <button
                                type="button"
                                onClick={handleSubmit}
                                disabled={isSubmitting}
                                className="rounded-xl bg-[#3997E0] px-6 py-2 text-base font-medium text-white hover:bg-blue-600 focus:outline-none disabled:opacity-50 disabled:cursor-not-allowed"
                            >
                                {isSubmitting ? "Saving..." : "Save Adjustment"}
                            </button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default NewStockAdjustmentModal;
