import { FC, useState } from "react";
import { useDealPageContext } from "../../../contexts/DealPageContext.tsx";
import {
    ActionIcon,
    Button,
    Checkbox,
    Divider,
    Fieldset,
    Flex,
    Group,
    rem,
    Textarea,
    TextInput,
    Tooltip,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import {
    ClientService,
    DealSchema,
    DealService,
    ProjectSchema,
    ShippingWarehouseSchema,
    StatusSchema,
} from "../../../../../client";
import { isEqual } from "lodash";
import { notifications } from "../../../../../shared/lib/notifications.ts";
import { useQueryClient } from "@tanstack/react-query";
import ShippingWarehouseAutocomplete
    from "../../../../../components/Selects/ShippingWarehouseAutocomplete/ShippingWarehouseAutocomplete.tsx";
import { ButtonCopyControlled } from "../../../../../components/ButtonCopyControlled/ButtonCopyControlled.tsx";
import { useClipboard } from "@mantine/hooks";
import ButtonCopy from "../../../../../components/ButtonCopy/ButtonCopy.tsx";
import FileSaver from "file-saver";
import { dateWithoutTimezone, getCurrentDateTimeForFilename } from "../../../../../shared/lib/date.ts";
import { IconBarcode, IconPrinter } from "@tabler/icons-react";
import styles from "../../../ui/DealsPage.module.css";
import { base64ToBlob } from "../../../../../shared/lib/utils.ts";
import { DatePickerInput } from "@mantine/dates";
import ManagerSelect from "../../../../../components/ManagerSelect/ManagerSelect.tsx";
import ProjectSelect from "../../../../../components/ProjectSelect/ProjectSelect.tsx";
import BoardSelect from "../../../../../components/BoardSelect/BoardSelect.tsx";
import DealStatusSelect from "../../../../../components/DealStatusSelect/DealStatusSelect.tsx";

type Props = {
    deal: DealSchema;
};

export type DealGeneralFormType = Omit<DealSchema, "statusHistory" | "services" | "products">;

const Content: FC<Props> = ({ deal }) => {
    const { setSelectedDeal } = useDealPageContext();
    const clipboard = useClipboard();
    const queryClient = useQueryClient();
    const [project, setProject] = useState<ProjectSchema | null>(deal.board.project);

    // ignore typescript

    const initialValues: DealGeneralFormType = {
        ...deal,
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-expect-error
        deliveryDate: deal.deliveryDate ? new Date(deal.deliveryDate) : null,
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-expect-error
        receivingSlotDate: deal.receivingSlotDate ? new Date(deal.receivingSlotDate) : null,
    };
    const form = useForm<DealGeneralFormType>({
        initialValues: initialValues,
        validate: {
            name: (value: string) =>
                value.length > 0
                    ? null
                    : "Название сделки не может быть пустым",
            status: (value: StatusSchema) =>
                !value && "Статус для сделки не выбран",
        },
    });
    const updateDealInfo = async (values: DealGeneralFormType) => {
        return DealService.updateDealGeneralInfo({
            requestBody: {
                dealId: deal.id,
                data: {
                    ...values,
                    shippingWarehouse: values.shippingWarehouse?.toString(),
                },
            },
        }).then(({ ok, message }) => {
            notifications.guess(ok, { message });
            if (!ok) return;
            DealService.getDealById({ dealId: deal.id }).then(data => {
                setSelectedDeal(data);
                form.setInitialValues(data);
                queryClient.invalidateQueries({
                    queryKey: ["getDealSummaries"],
                });
            });
        });
    };
    const updateClientInfo = async (values: DealGeneralFormType) => {
        return ClientService.updateClient({
            requestBody: {
                data: values.client,
            },
        }).then(({ ok, message }) => notifications.guess(ok, { message }));
    };
    const handleSubmit = async (values: DealGeneralFormType) => {
        // Updating client info if there changes
        if (!isEqual(values.client, deal.client)) {
            await updateClientInfo(values);
        }
        // updating deal info
        // get shimpent warehouse name from object if its object, otherwise just pass it
        const shippingWarehouse = isShippingWarehouse(values.shippingWarehouse) ? values.shippingWarehouse.name : values.shippingWarehouse;
        await updateDealInfo({
            ...values,
            deliveryDate: values.deliveryDate ? dateWithoutTimezone(new Date(values.deliveryDate)) : null,
            receivingSlotDate: values.receivingSlotDate ? dateWithoutTimezone(new Date(values.receivingSlotDate)) : null,
            shippingWarehouse: shippingWarehouse,
        });
    };
    const isShippingWarehouse = (
        value: ShippingWarehouseSchema | string | null | undefined,
    ): value is ShippingWarehouseSchema => {
        return !["string", "null", "undefined"].includes(typeof value);
    };

    const onCopyGuestUrlClick = () => {
        DealService.createDealGuestUrl({
            requestBody: {
                dealId: deal.id,
            },
        }).then(({ ok, message, url }) => {
            if (!ok) notifications.guess(ok, { message });
            clipboard.copy(`${window.location.origin}/${url}`);
        });
    };
    const billRequestPdfUrl = deal?.billRequest?.pdfUrl || deal?.group?.billRequest?.pdfUrl;

    return (
        <form onSubmit={form.onSubmit(values => handleSubmit(values))}>
            <Flex
                direction={"column"}
                justify={"space-between"}
                h={"100%"}>
                <Fieldset legend={`Общие параметры [ID: ${deal.id}]`}>
                    <Flex
                        direction={"column"}
                        gap={rem(10)}>
                        <TextInput
                            placeholder={"Название сделки"}
                            label={"Название сделки"}
                            {...form.getInputProps("name")}
                        />
                        <TextInput
                            disabled
                            placeholder={"Дата создания"}
                            label={"Дата создания"}
                            value={new Date(deal.createdAt).toLocaleString(
                                "ru-RU",
                            )}
                        />
                        <ProjectSelect
                            value={project}
                            onChange={setProject}
                            label={"Проект"}
                        />
                        <BoardSelect
                            project={project}
                            {...form.getInputProps("board")}
                            label={"Доска"}
                        />
                        <DealStatusSelect
                            board={form.values.board}
                            {...form.getInputProps("status")}
                            label={"Статус"}
                        />
                        <Textarea
                            h={rem(150)}
                            styles={{
                                wrapper: {height:'90%'},
                                input: {height:'90%'}
                            }}
                            label={"Коментарий к сделке"}
                            placeholder={"Введите коментарий к сделке"}
                            {...form.getInputProps("comment")}
                        />
                        <ShippingWarehouseAutocomplete
                            placeholder={"Введите склад отгрузки"}
                            label={"Склад отгрузки"}
                            value={
                                isShippingWarehouse(
                                    form.values.shippingWarehouse,
                                )
                                    ? form.values.shippingWarehouse
                                    : undefined
                            }
                            onChange={event => {
                                if (isShippingWarehouse(event)) {
                                    form.getInputProps(
                                        "shippingWarehouse",
                                    ).onChange(event.name);
                                    return;
                                }
                                form.getInputProps(
                                    "shippingWarehouse",
                                ).onChange(event);
                            }}
                        />
                        <DatePickerInput
                            minDate={new Date()}
                            placeholder={"Укажите дату передачи в доставку"}
                            label={"Дата передачи в доставку"}
                            {...form.getInputProps("deliveryDate")}

                        />
                        <DatePickerInput
                            minDate={new Date()}

                            placeholder={"Укажите слот приемки"}
                            label={"Слот приемки"}
                            {...form.getInputProps("receivingSlotDate")}

                        />
                        <ManagerSelect
                            placeholder={"Укажите менеджера"}
                            label={"Менеджер"}
                            {...form.getInputProps("manager")}
                        />
                    </Flex>
                </Fieldset>
                <Flex
                    mt={"md"}
                    gap={rem(10)}
                    align={"center"}
                    justify={"flex-end"}>
                    <Flex
                        align={"center"}
                        gap={rem(10)}
                        justify={"center"}>
                        <Flex
                            gap={rem(10)}
                            align={"center"}
                            justify={"space-between"}>
                            <Tooltip
                                className={styles["print-deals-button"]}
                                label={"Распечатать штрихкоды сделки"}
                            >
                                <ActionIcon
                                    onClick={async () => {
                                        const response =
                                            await DealService.getDealProductsBarcodesPdf({
                                                requestBody: {
                                                    dealId: deal.id,
                                                },
                                            });
                                        const pdfBlob = base64ToBlob(
                                            response.base64String,
                                            response.mimeType,
                                        );
                                        const pdfUrl = URL.createObjectURL(pdfBlob);
                                        const pdfWindow = window.open(pdfUrl);
                                        if (!pdfWindow) {
                                            notifications.error({ message: "Ошибка" });
                                            return;
                                        }
                                        pdfWindow.onload = () => {
                                            pdfWindow.print();
                                        };
                                    }}
                                    variant={"default"}>
                                    <IconBarcode />
                                </ActionIcon>
                            </Tooltip>

                            <Tooltip label={"Распечатать сделку"}>
                                <ActionIcon
                                    onClick={() => {
                                        const pdfWindow = window.open(
                                            `${import.meta.env.VITE_API_URL}/deal/tech-spec/${deal.id}`,
                                        );
                                        if (!pdfWindow) return;
                                        pdfWindow.print();
                                    }}
                                    variant={"default"}>
                                    <IconPrinter />
                                </ActionIcon>
                            </Tooltip>

                            <Flex gap={rem(10)}>
                                {billRequestPdfUrl ? (
                                    <ButtonCopy
                                        onCopiedLabel={
                                            "Ссылка скопирована в буфер обмена"
                                        }
                                        value={billRequestPdfUrl}>
                                        Ссылка на оплату
                                    </ButtonCopy>
                                ) : (
                                    <ButtonCopyControlled
                                        onCopyClick={() => {
                                            const date =
                                                getCurrentDateTimeForFilename();
                                            FileSaver.saveAs(
                                                `${import.meta.env.VITE_API_URL}/deal/billing-document/${deal.id}`,
                                                `bill_${deal.id}_${date}.pdf`,
                                            );
                                        }}
                                        copied={false}
                                        onCopiedLabel={
                                            "Ссылка скопирована в буфер обмена"
                                        }>
                                        Ссылка на оплату (PDF)
                                    </ButtonCopyControlled>
                                )}
                                <ButtonCopyControlled
                                    onCopyClick={onCopyGuestUrlClick}
                                    onCopiedLabel={
                                        "Ссылка скопирована в буфер обмена"
                                    }
                                    copied={clipboard.copied}>
                                    Ссылка на редактирование
                                </ButtonCopyControlled>
                            </Flex>
                        </Flex>
                        <Flex gap={rem(10)}>
                            <Checkbox
                                label={"Оплачен"}
                                checked={deal.billRequest?.paid || deal.group?.billRequest?.paid || false}
                                disabled
                            />
                            <Checkbox
                                label={"Учет выручки"}
                                {...form.getInputProps("isAccounted", { type: "checkbox" })}
                            />
                            <Checkbox
                                label={"Завершена"}
                                {...form.getInputProps("isCompleted", { type: "checkbox" })}
                            />
                            <Checkbox
                                label={"Удалена"}
                                {...form.getInputProps("isDeleted", { type: "checkbox" })}
                            />
                        </Flex>
                    </Flex>
                    <Divider orientation={"vertical"} />
                    <Group
                        align={"center"}
                        justify={"center"}>
                        <Button
                            color={"red"}
                            type={"reset"}
                            disabled={isEqual(initialValues, form.values)}
                            onClick={() => form.reset()}>
                            Отменить изменения
                        </Button>
                        <Button
                            variant={"default"}
                            type={"submit"}
                            disabled={isEqual(initialValues, form.values)}>
                            Сохранить изменения
                        </Button>
                    </Group>
                </Flex>
            </Flex>
        </form>
    );
};
const DealEditDrawerGeneralTab: FC = () => {
    const { selectedDeal } = useDealPageContext();
    if (!selectedDeal) return <>No deal selected</>;
    return <Content deal={selectedDeal} />;
};
export default DealEditDrawerGeneralTab;
