import { FC, useState } from "react";
import { useCardPageContext } from "../../../../contexts/CardPageContext.tsx";
import {
    Button,
    Checkbox,
    Divider,
    Fieldset,
    Flex,
    Group,
    rem,
    ScrollArea,
    Stack,
    Textarea,
    TextInput,
} from "@mantine/core";
import { useForm } from "@mantine/form";
import { CardSchema, CardService, ClientService, ProjectSchema, StatusSchema } from "../../../../../../client";
import { isEqual } from "lodash";
import { notifications } from "../../../../../../shared/lib/notifications.ts";
import { useQueryClient } from "@tanstack/react-query";
import { ButtonCopyControlled } from "../../../../../../components/ButtonCopyControlled/ButtonCopyControlled.tsx";
import { useClipboard } from "@mantine/hooks";
import ProjectSelect from "../../../../../../components/ProjectSelect/ProjectSelect.tsx";
import BoardSelect from "../../../../../../components/BoardSelect/BoardSelect.tsx";
import CardStatusSelect from "../../../../../../components/DealStatusSelect/CardStatusSelect.tsx";
import CardAttributeFields from "../../../../../../components/CardAttributeFields/CardAttributeFields.tsx";
import getAttributesFromCard from "../../../../../../components/CardAttributeFields/utils/getAttributesFromCard.ts";

type Props = {
    card: CardSchema;
};

type Attributes = {
    [key: string]: number | boolean | string;
};

export type CardGeneralFormType = Omit<CardSchema, "statusHistory" | "services" | "products">;

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

    const getInitialValues = (card: CardSchema): CardGeneralFormType => {
        return {
            ...card,
            ...getAttributesFromCard(card),
        };
    };

    let initialValues = getInitialValues(card);

    const form = useForm<CardGeneralFormType>({
        initialValues,
        validate: {
            name: (value: string) =>
                value.length > 0
                    ? null
                    : "Название не может быть пустым",
            status: (value: StatusSchema) =>
                !value && "Статус не выбран",
        },
    });

    const updateCardInfo = async (values: CardGeneralFormType) => {
        const formCardAttrs = values as unknown as Attributes;

        const attributes = project?.attributes.reduce((attrs, projectAttr) => {
            return {
                ...attrs,
                [projectAttr.name]: formCardAttrs[projectAttr.name],
            };
        }, {});

        return CardService.updateCardGeneralInfo({
            requestBody: {
                cardId: card.id,
                data: {
                    ...values,
                    statusId: values.status.id,
                    boardId: values.board.id,
                    clientId: values.client?.id ?? null,
                    attributes,
                },
            },
        }).then(({ ok, message }) => {
            notifications.guess(ok, { message });
            if (!ok) return;
            CardService.getCardById({ cardId: card.id }).then(data => {
                setSelectedCard(data);
                initialValues = getInitialValues(data);
                form.setValues(initialValues);
                queryClient.invalidateQueries({
                    queryKey: ["getCardSummaries"],
                });
            });
        });
    };
    const updateClientInfo = async (values: CardGeneralFormType) => {
        if (!values.client) return;
        return ClientService.updateClient({
            requestBody: {
                data: values.client,
            },
        }).then(({ ok, message }) => notifications.guess(ok, { message }));
    };
    const handleSubmit = async (values: CardGeneralFormType) => {
        // Updating client info if there changes
        if (!isEqual(values.client, card.client) && values.client?.id === card.clientId) {
            await updateClientInfo(values);
        }

        await updateCardInfo(values);
    };

    const onCopyGuestUrlClick = () => {
        CardService.createDealGuestUrl({
            requestBody: {
                cardId: card.id,
            },
        }).then(({ ok, message, url }) => {
            if (!ok) notifications.guess(ok, { message });
            clipboard.copy(`${window.location.origin}/${url}`);
        });
    };

    return (
        <form onSubmit={form.onSubmit(values => handleSubmit(values))}>
            <Flex
                direction={"column"}
                h={"95vh"}
            >
                <ScrollArea>
                    <Stack>
                        <Fieldset legend={`Общие параметры [ID: ${card.id}]`}>
                            <Flex
                                direction={"column"}
                                gap={rem(10)}
                            >
                                <TextInput
                                    placeholder={"Название сделки"}
                                    label={"Название сделки"}
                                    {...form.getInputProps("name")}
                                />
                                <TextInput
                                    disabled
                                    placeholder={"Дата создания"}
                                    label={"Дата создания"}
                                    value={new Date(card.createdAt).toLocaleString(
                                        "ru-RU",
                                    )}
                                />
                                <ProjectSelect
                                    value={project}
                                    onChange={setProject}
                                    label={"Проект"}
                                    disabled
                                />
                                <BoardSelect
                                    project={project}
                                    {...form.getInputProps("board")}
                                    label={"Доска"}
                                />
                                <CardStatusSelect
                                    board={form.values.board}
                                    {...form.getInputProps("status")}
                                    label={"Статус"}
                                />
                                <Textarea
                                    h={rem(120)}
                                    styles={{
                                        wrapper: { height: "90%" },
                                        input: { height: "90%" },
                                    }}
                                    label={"Коментарий"}
                                    placeholder={"Введите коментарий"}
                                    {...form.getInputProps("comment")}
                                />
                                {project && (
                                    <CardAttributeFields
                                        project={project}
                                        form={form}
                                    />
                                )}
                            </Flex>
                        </Fieldset>
                    </Stack>
                </ScrollArea>
                <Flex
                    mt={"md"}
                    gap={rem(10)}
                    align={"center"}
                    justify={"flex-end"}>
                    <Flex
                        align={"center"}
                        gap={rem(10)}
                        justify={"center"}>
                        <ButtonCopyControlled
                            onCopyClick={onCopyGuestUrlClick}
                            onCopiedLabel={
                                "Ссылка скопирована в буфер обмена"
                            }
                            copied={clipboard.copied}
                        >
                            Ссылка на редактирование
                        </ButtonCopyControlled>
                        <Flex gap={rem(10)}>
                            <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 GeneralTab: FC = () => {
    const { selectedCard } = useCardPageContext();
    if (!selectedCard) return <>No card selected</>;
    return (
        <Content card={selectedCard} />
    );
};

export default GeneralTab;
