import React, { useEffect, useState } from "react";
import { InertiaFormProps } from "@inertiajs/react";
import { route } from "ziggy-js";
import axios from "axios";
import { Button, Stack, TextInput, NumberInput, Loader, Select, Switch, Text } from "@mantine/core";
import { DateInput } from "@mantine/dates";
import { IconDeviceFloppy } from "@tabler/icons-react";
import dayjs from "dayjs";

export interface InvoiceFormValues {
    invoice_no: string;
    linked_invoice_id: string;
    is_credit_card: boolean;
    is_paid: boolean;
    payment_no: string;
    start_date: string;
    end_date: string;
    amount: string;
    management_fee: string;
    media_fee: string;
    tax_percent: string;
    total_spending: string;
    client_id?: string;
    customer_id?: string;
}

interface InvoiceOption {
    value: string;
    label: string;
}

interface Props {
    form: InertiaFormProps<InvoiceFormValues>;
    onSubmit: (event: React.FormEvent<HTMLFormElement>) => void;
    submitLabel?: string;
    invoiceOptions?: InvoiceOption[];
}

export default function InvoiceForm({
    form,
    onSubmit,
    submitLabel = "Save invoice",
    invoiceOptions = [],
}: Props) {
    const formatDate = (value: string) => (value ? dayjs(value).toDate() : null);
    const [fetchingSpend, setFetchingSpend] = useState(false);

    useEffect(() => {
        if (!form.data.is_credit_card) return;

        // Credit-card invoices can be fee-free; normalize fields to 0 for convenience.
        if (form.data.management_fee !== "0") form.setData("management_fee", "0");
        if (form.data.media_fee !== "0") form.setData("media_fee", "0");
        if (form.data.tax_percent !== "0") form.setData("tax_percent", "0");
    }, [form.data.is_credit_card]);

    useEffect(() => {
        const startDate = form.data.start_date;
        const endDate = form.data.end_date;
        const customerId = form.data.customer_id;

        if (!startDate || !endDate) {
            form.setData("total_spending", "0");
            setFetchingSpend(false);
            return;
        }

        let canceled = false;
        setFetchingSpend(true);

        axios
            .post(
                route("google.getCampaignsDetails"),
                {
                    clientCustomerId: customerId,
                    startDate,
                    endDate,
                },
                {
                    withCredentials: true,
                }
            )
            .then((response) => {
                if (canceled) return;

                const value = parseFloat(response.data?.summary?.total_actual_spend ?? 0) || 0;
                const formatted = value.toFixed(2);
                form.setData("total_spending", formatted);
            })
            .catch(() => {
                if (!canceled) {
                    form.setData("total_spending", "");
                }
            })
            .finally(() => {
                if (!canceled) {
                    setFetchingSpend(false);
                }
            });

        return () => {
            canceled = true;
        };
    }, [form.data.start_date, form.data.end_date, form.data.customer_id]);

    return (
        <form onSubmit={onSubmit}>
            <Stack spacing="xl">
                <TextInput
                    label="Invoice number"
                    value={form.data.invoice_no}
                    onChange={(event) => form.setData("invoice_no", event.target.value)}
                    error={form.errors.invoice_no}
                    required
                />

                <Select
                    label="Linked invoice"
                    description="Leave blank if this invoice should stay independent."
                    data={invoiceOptions}
                    value={form.data.linked_invoice_id || null}
                    onChange={(value) => form.setData("linked_invoice_id", value ?? "")}
                    error={form.errors.linked_invoice_id}
                    clearable
                    searchable
                    nothingFound="No invoices available"
                />

                <TextInput
                    label="Payment No"
                    value={form.data.payment_no}
                    onChange={(event) => form.setData("payment_no", event.target.value)}
                    error={form.errors.payment_no}
                />

                <DateInput
                    label="Start date"
                    value={formatDate(form.data.start_date)}
                    onChange={(value) =>
                        form.setData("start_date", value ? dayjs(value).format("YYYY-MM-DD") : "")
                    }
                    error={form.errors.start_date}
                    clearable
                />

                <DateInput
                    label="End date"
                    value={formatDate(form.data.end_date)}
                    onChange={(value) =>
                        form.setData("end_date", value ? dayjs(value).format("YYYY-MM-DD") : "")
                    }
                    error={form.errors.end_date}
                    clearable
                />

                <NumberInput
                    precision={2}
                    step={0.01}
                    label="Management fee"
                    value={form.data.management_fee !== "" ? Number(form.data.management_fee) : undefined}
                    onChange={(value) => form.setData("management_fee", value?.toString() ?? "")}
                    error={form.errors.management_fee}
                    required
                />

                <NumberInput
                    precision={2}
                    step={0.01}
                    label="Media fee"
                    value={form.data.media_fee !== "" ? Number(form.data.media_fee) : undefined}
                    onChange={(value) => form.setData("media_fee", value?.toString() ?? "")}
                    error={form.errors.media_fee}
                    required
                />

                <NumberInput
                    precision={2}
                    step={0.01}
                    label="Withholding Tax (%)"
                    value={form.data.tax_percent !== "" ? Number(form.data.tax_percent) : undefined}
                    onChange={(value) => form.setData("tax_percent", value?.toString() ?? "")}
                    error={form.errors.tax_percent}
                    required
                />

                <NumberInput
                    precision={2}
                    label="Total Spending (RM)"
                    value={form.data.total_spending !== "" ? Number(form.data.total_spending) : undefined}
                    onChange={(value) => form.setData("total_spending", value?.toString() ?? "")}
                    rightSection={fetchingSpend ? <Loader size="xs" /> : null}
                />

                <Text>Additional Info</Text>
                <Switch
                    label="Credit card"
                    checked={form.data.is_credit_card}
                    onChange={(event) => form.setData("is_credit_card", event.currentTarget.checked)}
                />

                <Switch
                    label="Paid"
                    checked={form.data.is_paid}
                    onChange={(event) => form.setData("is_paid", event.currentTarget.checked)}
                />

                <Button
                    type="submit"
                    loading={form.processing}
                    leftIcon={<IconDeviceFloppy size={16} />}
                    style={{ width: "max-content" }}
                >
                    {submitLabel}
                </Button>
            </Stack>
        </form>
    );
}
