'use client';

import { Save } from 'lucide-react';
import { ICON_SIZE_MD } from '@/components/icons';
import React, { useEffect, useMemo } from 'react';
import { Modal, Form, Row, Col, Button, Switch, Space, Divider, Typography } from 'antd';
import { message } from '@/lib/feedback/message';
import { WaygestFormModalLoadingBody } from '@/components/modals/waygestFormModal';
import {
    mergeWaygestFormModalBodyStyles,
    useWaygestFormModalProps,
    waygestFormModalFooterClassName,
} from '@/hooks/useWaygestFormModalProps';
import { useConfirmModalClose } from '@/hooks/useConfirmModalClose';
import {
    FormInput,
    FormRichEditor,
    FormSelect,
    FormNumber,
    FormDatePicker,
} from '@/components/form';
import { useQueryCache } from '@/hooks/useQueryCache';
import { queryKeys } from '@/lib/cache/queryKeys';
import {
    parametrosCatalogSelectBindings,
    type ParametrosCatalogSelectQueryState,
} from '@/hooks/useParametrosCatalogSelect';
import { useMutationCache } from '@/hooks/useMutationCache';
import { API_ENDPOINTS } from '@/lib/api/endpoints';
import { getLaravelApiErrorMessage } from '@/lib/api/laravelApiErrorMessage';
import { useAuth } from '@/contexts/AuthContext';
import { useProductMicrocopy } from '@/lib/i18n/productMicrocopy';
import { Tarefa } from '@/types';
import dayjs from 'dayjs';

const TAREFA_FORM_ID = 'tarefa-form-modal-form';

const TIPO_OPTIONS = [
    { label: 'Feature', value: 'feature' },
    { label: 'Bug', value: 'bug' },
    { label: 'Refatoração', value: 'refatoracao' },
    { label: 'Teste', value: 'teste' },
    { label: 'Documentação', value: 'documentacao' },
    { label: 'DevOps', value: 'devops' },
];

const { Text } = Typography;

export interface TarefaFormModalProps {
    open: boolean;
    onClose: () => void;
    /** Se informado, modo edição; senão, modo criação */
    tarefa?: Tarefa | null;
    /** Callback após criar/atualizar com sucesso (para invalidar listas/kanban) */
    onSuccess?: () => void;
    /** ID do projeto pré-selecionado (para criação) */
    projetoIdPadrao?: number;
    /** Status inicial (para criação a partir de uma coluna do Kanban) */
    statusInicial?: string;
    /** Board inicial (funil) – para criação a partir do Kanban por coluna */
    boardIdInicial?: number;
    /** Etapa inicial (coluna do board) – para criação a partir do Kanban por coluna */
    boardEtapaIdInicial?: number;
}

export function TarefaFormModal({
    open,
    onClose,
    tarefa,
    onSuccess,
    projetoIdPadrao,
    statusInicial,
    boardIdInicial,
    boardEtapaIdInicial,
}: TarefaFormModalProps) {
    const cfgPt = useProductMicrocopy();
    const { user } = useAuth();
    const [form] = Form.useForm();
    const vincularProjeto = Form.useWatch('vincular_projeto', form) ?? false;
    const projetoId = Form.useWatch('projeto_id', form);
    const boardId = Form.useWatch('board_id', form);
    const isEdit = !!tarefa?.id;
    const formModalLayout = useWaygestFormModalProps();
    const handleCloseModal = useConfirmModalClose(form, onClose);

    const { data: tarefaDetail, isLoading: loadingTarefaDetail } = useQueryCache<Tarefa>({
        queryKey: queryKeys.desenvolvimento.tarefas.detail(tarefa?.id ?? 0),
        endpoint: tarefa?.id ? API_ENDPOINTS.desenvolvimento.tarefas.show(tarefa.id) : '',
        enabled: open && isEdit && !!tarefa?.id,
    });

    const { data: projetosData } = useQueryCache<{ data: Array<{ id: number; nome: string }> }>({
        queryKey: queryKeys.projetos.listScoped('modal'),
        endpoint: API_ENDPOINTS.projetos.index,
        params: { per_page: 500, page: 1 },
        parametrosCatalog: true,
        enabled: open,
    });

    const { data: sprintsData } = useQueryCache<{
        data: Array<{ id: number; nome: string; projeto_id?: number }>;
    }>({
        queryKey: queryKeys.minhasTarefas.catalogs.sprintsModal(projetoId),
        endpoint: API_ENDPOINTS.desenvolvimento.sprints.index,
        params: { per_page: 500, page: 1, ...(projetoId && { projeto_id: projetoId }) },
        parametrosCatalog: true,
        enabled: open && !!projetoId,
    });

    const { data: entregasData } = useQueryCache<{
        data: Array<{ id: number; titulo: string; codigo?: string; projeto_id?: number }>;
    }>({
        queryKey: queryKeys.minhasTarefas.catalogs.entregasModal(projetoId),
        endpoint: API_ENDPOINTS.entregas.index,
        params: { per_page: 500, page: 1, ...(projetoId && { projeto_id: projetoId }) },
        parametrosCatalog: true,
        enabled: open && !!projetoId,
    });

    const { data: usuariosData } = useQueryCache<{ data: Array<{ id: number; nome: string }> }>({
        queryKey: queryKeys.usuariosCatalog.list('modal'),
        endpoint: API_ENDPOINTS.admin.usuarios.index,
        params: { per_page: 500, page: 1 },
        parametrosCatalog: true,
        enabled: open,
    });

    const {
        data: statusTarefaData,
        isLoading: statusTarefaSelectLoading,
        isError: statusTarefaSelectIsError,
        refetch: refetchStatusTarefaSelect,
        error: statusTarefaSelectError,
    } = useQueryCache<{
        data: Array<{ id: number; nome: string; slug: string | null; ordem: number }>;
    }>({
        queryKey: queryKeys.minhasTarefas.catalogs.statusTarefa('modal'),
        endpoint: API_ENDPOINTS.statusTarefa.index,
        parametrosCatalog: true,
        enabled: open,
    });

    const {
        data: prioridadeTarefaData,
        isLoading: prioridadeSelectLoading,
        isError: prioridadeSelectIsError,
        refetch: refetchPrioridadeSelect,
        error: prioridadeSelectError,
    } = useQueryCache<{
        data: Array<{ id: number; nome: string; codigo: string | null; ordem: number }>;
    }>({
        queryKey: queryKeys.minhasTarefas.catalogs.prioridadesTarefa('modal'),
        endpoint: API_ENDPOINTS.prioridadesTarefa.index,
        parametrosCatalog: true,
        enabled: open,
    });

    const { data: boardsData } = useQueryCache<{
        data: Array<{ id: number; nome: string; cor?: string; icone?: string }>;
    }>({
        queryKey: queryKeys.tarefas.quadros.list({ scope: 'modal' }),
        endpoint: API_ENDPOINTS.tarefas.quadros.index,
        parametrosCatalog: true,
        enabled: open,
    });

    const { data: etapasData } = useQueryCache<{
        data: Array<{ id: number; board_id?: number; nome: string; cor?: string; ordem: number }>;
    }>({
        queryKey: queryKeys.tarefas.boards.etapas(boardId ?? 0),
        endpoint: API_ENDPOINTS.tarefas.boards.etapas(boardId ?? 0),
        parametrosCatalog: true,
        enabled: open && !!boardId,
    });

    const statusOptions =
        statusTarefaData?.data?.map((s) => ({
            label: s.nome,
            value: s.slug ?? s.nome,
        })) ?? [];

    /** A tarefa grava o código da prioridade, não o id do pré-cadastro. */
    const prioridadeOptions =
        prioridadeTarefaData?.data
            ?.filter((p) => !!p.codigo)
            .slice()
            .sort((a, b) => a.ordem - b.ordem)
            .map((p) => ({ label: p.nome, value: p.codigo as string })) ?? [];

    /** Catálogo fixo (API valida enum) — paridade UX com selects do modal de compromissos. */
    const catalogoEstaticoQueryState = useMemo<ParametrosCatalogSelectQueryState>(
        () => ({
            isLoading: false,
            isError: false,
            refetch: () => {
                /* sem fetch */
            },
            error: undefined,
        }),
        [],
    );

    const statusTarefaSelectQueryState = useMemo<ParametrosCatalogSelectQueryState>(
        () => ({
            isLoading: statusTarefaSelectLoading,
            isError: statusTarefaSelectIsError,
            refetch: refetchStatusTarefaSelect,
            error: statusTarefaSelectError,
        }),
        [
            statusTarefaSelectLoading,
            statusTarefaSelectIsError,
            refetchStatusTarefaSelect,
            statusTarefaSelectError,
        ],
    );
    const prioridadeSelectQueryState = useMemo<ParametrosCatalogSelectQueryState>(
        () => ({
            isLoading: prioridadeSelectLoading,
            isError: prioridadeSelectIsError,
            refetch: refetchPrioridadeSelect,
            error: prioridadeSelectError,
        }),
        [
            prioridadeSelectLoading,
            prioridadeSelectIsError,
            refetchPrioridadeSelect,
            prioridadeSelectError,
        ],
    );

    const boards = boardsData?.data ?? [];
    const etapas = etapasData?.data ?? [];

    const projetos = projetosData?.data ?? [];
    const sprints = sprintsData?.data ?? [];
    const entregas = entregasData?.data ?? [];
    const usuarios = usuariosData?.data ?? [];

    const createMutation = useMutationCache<Record<string, unknown>, Record<string, unknown>>({
        endpoint: API_ENDPOINTS.desenvolvimento.tarefas.store,
        method: 'POST',
        invalidateQueries: [
            queryKeys.minhasTarefas.all,
            ['desenvolvimento', 'tarefas'],
            ['desenvolvimento', 'board'],
        ],
        onSuccess: () => {
            message.success('Tarefa criada com sucesso!');
            form.resetFields();
            onClose();
            onSuccess?.();
        },
        onError: (err: unknown) => {
            message.error(getLaravelApiErrorMessage(err, 'Erro ao criar tarefa'));
        },
    });

    const updateMutation = useMutationCache<Tarefa, Partial<Tarefa>>({
        endpoint: API_ENDPOINTS.desenvolvimento.tarefas.update(tarefa?.id ?? 0),
        method: 'PUT',
        invalidateQueries: [
            queryKeys.minhasTarefas.all,
            ['tarefa-desenvolvimento', tarefa?.id],
            ['desenvolvimento', 'tarefas'],
            ...(tarefa?.id ? [queryKeys.desenvolvimento.tarefas.detail(tarefa.id)] : []),
        ],
        onSuccess: () => {
            message.success('Tarefa atualizada com sucesso!');
            form.resetFields();
            onClose();
            onSuccess?.();
        },
        onError: (err: unknown) => {
            message.error(getLaravelApiErrorMessage(err, 'Erro ao atualizar tarefa'));
        },
    });

    useEffect(() => {
        if (!open) return;
        const source = tarefaDetail ?? tarefa;
        if (source?.id) {
            const hasProjeto = !!(source.projeto_id ?? undefined);
            form.setFieldsValue({
                titulo: source.titulo,
                descricao: source.descricao ?? undefined,
                vincular_projeto: hasProjeto,
                projeto_id: source.projeto_id ?? undefined,
                sprint_id: source.sprint_id ?? undefined,
                entrega_id: source.entrega_id ?? undefined,
                tipo: source.tipo ?? 'feature',
                status: source.status ?? 'novo',
                prioridade: source.prioridade ?? 'media',
                responsavel_id: source.responsavel_id ?? undefined,
                board_id: source.board_id ?? undefined,
                board_coluna_id: source.board_coluna_id ?? source.board_etapa_id ?? undefined,
                estimativa: source.estimativa ?? undefined,
                data_vencimento: source.data_vencimento
                    ? dayjs(source.data_vencimento)
                    : undefined,
            });
        } else {
            form.setFieldsValue({
                tipo: 'feature',
                status: statusInicial ?? 'novo',
                prioridade: 'media',
                vincular_projeto: !!projetoIdPadrao,
                projeto_id: projetoIdPadrao ?? undefined,
                sprint_id: undefined,
                entrega_id: undefined,
                board_id: boardIdInicial ?? undefined,
                board_coluna_id: boardEtapaIdInicial ?? undefined,
                responsavel_id: user?.id,
            });
        }
    }, [
        open,
        tarefa,
        tarefaDetail,
        statusInicial,
        projetoIdPadrao,
        boardIdInicial,
        boardEtapaIdInicial,
        user?.id,
        form,
    ]);

    const handleSubmit = (values: Record<string, unknown>) => {
        const payload: Record<string, unknown> = { ...values };
        if (payload.data_vencimento && dayjs.isDayjs(payload.data_vencimento)) {
            payload.data_vencimento = payload.data_vencimento.format('YYYY-MM-DD');
        }
        const vincular = payload.vincular_projeto === true;
        delete payload.vincular_projeto;
        if (!vincular) {
            payload.projeto_id = undefined;
            payload.sprint_id = undefined;
            payload.entrega_id = undefined;
        }
        if (isEdit) {
            updateMutation.mutate(payload as Partial<Tarefa>);
        } else {
            createMutation.mutate(payload as Record<string, unknown>);
        }
    };

    const isPending = createMutation.isPending || updateMutation.isPending;
    const loadingDetail = isEdit && loadingTarefaDetail && !tarefaDetail;

    return (
        <Modal
            data-testid="tarefa-form-modal"
            title={isEdit ? 'Editar tarefa' : 'Nova tarefa'}
            open={open}
            onCancel={handleCloseModal}
            width={formModalLayout.width ?? 720}
            centered={formModalLayout.centered ?? true}
            className={formModalLayout.className}
            styles={mergeWaygestFormModalBodyStyles(formModalLayout)}
            zIndex={formModalLayout.zIndex}
            footer={
                <div className={waygestFormModalFooterClassName}>
                    <Button onClick={handleCloseModal} disabled={isPending}>
                        Cancelar
                    </Button>
                    <Button
                        type="primary"
                        htmlType="submit"
                        form={TAREFA_FORM_ID}
                        loading={isPending}
                        disabled={loadingDetail}
                        icon={<Save size={ICON_SIZE_MD} aria-hidden />}
                    >
                        {isEdit ? cfgPt.save : 'Criar tarefa'}
                    </Button>
                </div>
            }
            destroyOnHidden
            keyboard
            focusTriggerAfterClose
            maskClosable={!isPending}
            closable={!isPending}
        >
            <WaygestFormModalLoadingBody loading={loadingDetail} tip="Carregando tarefa…">
                <Form
                    id={TAREFA_FORM_ID}
                    form={form}
                    layout="vertical"
                    preserve={false}
                    onFinish={handleSubmit}
                >
                    <Divider orientation="left">Identificação</Divider>
                    <Text type="secondary" style={{ display: 'block', marginBottom: 16 }}>
                        Título e descrição visíveis no Kanban e nas listagens.
                    </Text>
                    <FormInput
                        name="titulo"
                        label="Título"
                        required
                        placeholder="Título da tarefa"
                    />
                    <FormRichEditor
                        name="descricao"
                        label="Descrição"
                        placeholder="Descreva a tarefa..."
                        minHeight={160}
                    />

                    <Divider orientation="left">Quadro Kanban</Divider>
                    <Text type="secondary" style={{ display: 'block', marginBottom: 16 }}>
                        Board e coluna onde a tarefa aparece no fluxo de trabalho.
                    </Text>
                    <Row gutter={16}>
                        <Col xs={24} sm={12}>
                            <FormSelect
                                name="board_id"
                                label="Board"
                                placeholder="Selecione o board"
                                allowClear
                                showSearch
                                optionFilterProp="label"
                                options={boards.map((b) => ({ label: b.nome, value: b.id }))}
                                onChange={() => form.setFieldsValue({ board_coluna_id: undefined })}
                            />
                        </Col>
                        <Col xs={24} sm={12}>
                            <FormSelect
                                name="board_coluna_id"
                                label="Etapa (coluna)"
                                placeholder={
                                    boardId ? 'Selecione a etapa' : 'Selecione o board primeiro'
                                }
                                allowClear
                                showSearch
                                optionFilterProp="label"
                                options={etapas.map((e) => ({ label: e.nome, value: e.id }))}
                                disabled={!boardId}
                            />
                        </Col>
                    </Row>

                    <Divider orientation="left">Classificação</Divider>
                    <Row gutter={16}>
                        <Col xs={24} sm={12}>
                            <FormSelect
                                name="tipo"
                                label="Tipo"
                                placeholder="Selecione"
                                options={TIPO_OPTIONS}
                                {...parametrosCatalogSelectBindings(catalogoEstaticoQueryState)}
                            />
                        </Col>
                        <Col xs={24} sm={12}>
                            <FormSelect
                                name="status"
                                label="Status"
                                placeholder="Selecione"
                                options={statusOptions}
                                {...parametrosCatalogSelectBindings(statusTarefaSelectQueryState)}
                            />
                        </Col>
                    </Row>
                    <Row gutter={16}>
                        <Col xs={24} sm={12}>
                            <FormSelect
                                name="prioridade"
                                label="Prioridade"
                                placeholder="Selecione"
                                options={prioridadeOptions}
                                {...parametrosCatalogSelectBindings(prioridadeSelectQueryState)}
                            />
                        </Col>
                        <Col xs={24} sm={12}>
                            <FormSelect
                                name="responsavel_id"
                                label="Responsável"
                                placeholder="Selecione o responsável"
                                allowClear
                                showSearch
                                optionFilterProp="label"
                                options={usuarios.map((u) => ({ label: u.nome, value: u.id }))}
                            />
                        </Col>
                    </Row>

                    <Divider orientation="left">Prazo e estimativa</Divider>
                    <Row gutter={16}>
                        <Col xs={24} sm={12}>
                            <FormNumber
                                name="estimativa"
                                label="Estimativa (horas)"
                                placeholder="0"
                                min={0}
                            />
                        </Col>
                        <Col xs={24} sm={12}>
                            <FormDatePicker
                                name="data_vencimento"
                                label="Data de vencimento"
                                format="DD/MM/YYYY"
                            />
                        </Col>
                    </Row>

                    <Divider orientation="left">Vínculo com projeto</Divider>
                    <Space
                        style={{
                            width: '100%',
                            justifyContent: 'space-between',
                            marginBottom: vincularProjeto ? 16 : 0,
                        }}
                    >
                        <Text type="secondary">
                            Associe a tarefa a um projeto, sprint ou entrega.
                        </Text>
                        <Form.Item name="vincular_projeto" valuePropName="checked" noStyle>
                            <Switch
                                checkedChildren="Sim"
                                unCheckedChildren="Não"
                                onChange={(checked) => {
                                    form.setFieldValue('vincular_projeto', checked);
                                    if (!checked) {
                                        form.setFieldsValue({
                                            projeto_id: undefined,
                                            sprint_id: undefined,
                                            entrega_id: undefined,
                                        });
                                    }
                                }}
                            />
                        </Form.Item>
                    </Space>
                    {vincularProjeto ? (
                        <>
                            <FormSelect
                                name="projeto_id"
                                label="Projeto"
                                placeholder="Selecione o projeto"
                                allowClear
                                showSearch
                                optionFilterProp="label"
                                options={projetos.map((p) => ({ label: p.nome, value: p.id }))}
                                onChange={(value) => {
                                    form.setFieldsValue({
                                        projeto_id: value ?? undefined,
                                        sprint_id: undefined,
                                        entrega_id: undefined,
                                    });
                                }}
                            />
                            {projetoId ? (
                                <Row gutter={16}>
                                    <Col xs={24} sm={12}>
                                        <FormSelect
                                            name="sprint_id"
                                            label="Sprint"
                                            placeholder="Selecione a sprint"
                                            allowClear
                                            showSearch
                                            optionFilterProp="label"
                                            options={sprints.map((s) => ({
                                                label: s.nome,
                                                value: s.id,
                                            }))}
                                        />
                                    </Col>
                                    <Col xs={24} sm={12}>
                                        <FormSelect
                                            name="entrega_id"
                                            label="Entrega"
                                            placeholder="Selecione a entrega"
                                            allowClear
                                            showSearch
                                            optionFilterProp="label"
                                            options={entregas.map((e) => ({
                                                label: e.codigo
                                                    ? `${e.codigo} - ${e.titulo}`
                                                    : e.titulo,
                                                value: e.id,
                                            }))}
                                        />
                                    </Col>
                                </Row>
                            ) : null}
                        </>
                    ) : null}
                </Form>
            </WaygestFormModalLoadingBody>
        </Modal>
    );
}
