import React, { useEffect, useMemo, useState } from "react";
import { useParams, useNavigate } from "react-router-dom";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
  Spin,
  Alert,
  Button,
  Form,
  Select,
  DatePicker,
  Input,
  Typography,
  message,
  Row,
  Col,
  Affix,
  Modal,
  Tag,
  Image,
} from "antd";
import {
  ArrowLeftOutlined,
  CheckOutlined,
  DeleteOutlined,
  ExclamationCircleFilled,
  RestOutlined,
  PlusOutlined,
  FileImageOutlined,
  SwapOutlined,
} from "@ant-design/icons";
import dayjs from "dayjs";
import { api, getStaticUrl } from "../services/api";
import { DraftItemRow } from "../components/invoices/DraftItemRow";
import type {
  UpdateDraftItemRequest,
  CommitDraftRequest,
  ReorderDraftItemsRequest,
} from "../services/types";
import { DragDropContext, Droppable, type DropResult } from "@hello-pangea/dnd";

const { Text } = Typography;
const { TextArea } = Input;
const { confirm } = Modal;

export const InvoiceDraftPage: React.FC = () => {
  const { id } = useParams<{ id: string }>();
  const navigate = useNavigate();
  const queryClient = useQueryClient();
  const [form] = Form.useForm();

  const [updatingItems, setUpdatingItems] = useState<Set<string>>(new Set());
  const [itemsOrder, setItemsOrder] = useState<Record<string, number>>({});
  const [isDragging, setIsDragging] = useState(false);
  const [isReordering, setIsReordering] = useState(false);

  // Состояние для просмотра фото чека
  const [previewVisible, setPreviewVisible] = useState(false);

  // --- ЗАПРОСЫ ---

  const dictQuery = useQuery({
    queryKey: ["dictionaries"],
    queryFn: api.getDictionaries,
    staleTime: 1000 * 60 * 5,
  });

  const recommendationsQuery = useQuery({
    queryKey: ["recommendations"],
    queryFn: api.getRecommendations,
  });

  const draftQuery = useQuery({
    queryKey: ["draft", id],
    queryFn: () => api.getDraft(id!),
    enabled: !!id,
    refetchInterval: (query) => {
      if (isDragging) return false;
      const status = query.state.data?.status;
      return status === "PROCESSING" ? 3000 : false;
    },
  });

  const draft = draftQuery.data;
  const stores = dictQuery.data?.stores || [];
  const suppliers = dictQuery.data?.suppliers || [];

  // --- МУТАЦИИ ---

  const updateItemMutation = useMutation({
    mutationFn: (vars: { itemId: string; payload: UpdateDraftItemRequest }) =>
      api.updateDraftItem(id!, vars.itemId, vars.payload),
    onMutate: async ({ itemId }) => {
      setUpdatingItems((prev) => new Set(prev).add(itemId));
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ["draft", id] });
    },
    onError: () => {
      message.error("Не удалось сохранить строку");
    },
    onSettled: (_data, _err, vars) => {
      setUpdatingItems((prev) => {
        const next = new Set(prev);
        next.delete(vars.itemId);
        return next;
      });
    },
  });

  const addItemMutation = useMutation({
    mutationFn: () => api.addDraftItem(id!),
    onSuccess: () => {
      message.success("Строка добавлена");
      queryClient.invalidateQueries({ queryKey: ["draft", id] });
    },
    onError: () => {
      message.error("Ошибка создания строки");
    },
  });

  const deleteItemMutation = useMutation({
    mutationFn: (itemId: string) => api.deleteDraftItem(id!, itemId),
    onSuccess: () => {
      message.success("Строка удалена");
      queryClient.invalidateQueries({ queryKey: ["draft", id] });
    },
    onError: () => {
      message.error("Ошибка удаления строки");
    },
  });

  const commitMutation = useMutation({
    mutationFn: (payload: CommitDraftRequest) => api.commitDraft(id!, payload),
    onSuccess: (data) => {
      message.success(`Накладная ${data.document_number} создана!`);
      navigate("/invoices");
      queryClient.invalidateQueries({ queryKey: ["drafts"] });
    },
    onError: () => {
      message.error("Ошибка при создании накладной");
    },
  });

  const deleteDraftMutation = useMutation({
    mutationFn: () => api.deleteDraft(id!),
    onSuccess: () => {
      if (draft?.status === "CANCELED") {
        message.info("Черновик удален окончательно");
        navigate("/invoices");
      } else {
        message.warning("Черновик отменен");
        queryClient.invalidateQueries({ queryKey: ["draft", id] });
      }
    },
    onError: () => {
      message.error("Ошибка при удалении");
    },
  });

  const reorderItemsMutation = useMutation({
    mutationFn: ({
      draftId,
      payload,
    }: {
      draftId: string;
      payload: ReorderDraftItemsRequest;
    }) => api.reorderDraftItems(draftId, payload),
    onError: (error) => {
      message.error("Не удалось изменить порядок элементов");
      console.error("Reorder error:", error);
    },
  });

  // --- ЭФФЕКТЫ ---

  useEffect(() => {
    if (draft) {
      const currentValues = form.getFieldsValue();
      if (!currentValues.store_id && draft.store_id)
        form.setFieldValue("store_id", draft.store_id);
      if (!currentValues.supplier_id && draft.supplier_id)
        form.setFieldValue("supplier_id", draft.supplier_id);
      if (!currentValues.comment && draft.comment)
        form.setFieldValue("comment", draft.comment);

      // Инициализация входящего номера
      if (
        !currentValues.incoming_document_number &&
        draft.incoming_document_number
      )
        form.setFieldValue(
          "incoming_document_number",
          draft.incoming_document_number
        );

      if (!currentValues.date_incoming)
        form.setFieldValue(
          "date_incoming",
          draft.date_incoming ? dayjs(draft.date_incoming) : dayjs()
        );
    }
  }, [draft, form]);

  // --- ХЕЛПЕРЫ ---
  const totalSum = useMemo(() => {
    return (
      draft?.items.reduce(
        (acc, item) => acc + Number(item.quantity) * Number(item.price),
        0
      ) || 0
    );
  }, [draft?.items]);

  const invalidItemsCount = useMemo(() => {
    return draft?.items.filter((i) => !i.product_id).length || 0;
  }, [draft?.items]);

  const handleItemUpdate = (
    itemId: string,
    changes: UpdateDraftItemRequest
  ) => {
    updateItemMutation.mutate({ itemId, payload: changes });
  };

  const handleCommit = async () => {
    try {
      const values = await form.validateFields();

      if (invalidItemsCount > 0) {
        message.warning(
          `Осталось ${invalidItemsCount} нераспознанных товаров!`
        );
        return;
      }

      commitMutation.mutate({
        date_incoming: values.date_incoming.format("YYYY-MM-DD"),
        store_id: values.store_id,
        supplier_id: values.supplier_id,
        comment: values.comment || "",
        incoming_document_number: values.incoming_document_number || "",
      });
    } catch {
      message.error("Заполните обязательные поля (Склад, Поставщик)");
    }
  };

  const isCanceled = draft?.status === "CANCELED";

  const handleDelete = () => {
    confirm({
      title: isCanceled ? "Удалить окончательно?" : "Отменить черновик?",
      icon: <ExclamationCircleFilled style={{ color: "red" }} />,
      content: isCanceled
        ? "Черновик пропадет из списка навсегда."
        : 'Черновик получит статус "Отменен", но останется в списке.',
      okText: isCanceled ? "Удалить навсегда" : "Отменить",
      okType: "danger",
      cancelText: "Назад",
      onOk() {
        deleteDraftMutation.mutate();
      },
    });
  };

  const handleDragStart = () => {
    setIsDragging(true);
  };

  const handleDragEnd = async (result: DropResult) => {
    setIsDragging(false);
    const { source, destination } = result;

    // Если нет назначения или позиция не изменилась
    if (
      !destination ||
      (source.droppableId === destination.droppableId &&
        source.index === destination.index)
    ) {
      return;
    }

    if (!draft) return;

    // Сохраняем предыдущее состояние для отката
    const previousItems = [...draft.items];
    const previousOrder = { ...itemsOrder };

    // Создаём новый массив с изменённым порядком
    const newItems = [...draft.items];
    const [removed] = newItems.splice(source.index, 1);
    newItems.splice(destination.index, 0, removed);

    // Обновляем локальное состояние немедленно для быстрого UI
    queryClient.setQueryData(["draft", id], {
      ...draft,
      items: newItems,
    });

    // Подготавливаем payload для API
    const reorderPayload: ReorderDraftItemsRequest = {
      items: newItems.map((item, index) => ({
        id: item.id,
        order: index,
      })),
    };

    // Отправляем запрос на сервер
    try {
      await reorderItemsMutation.mutateAsync({
        draftId: draft.id,
        payload: reorderPayload,
      });
    } catch {
      // При ошибке откатываем локальное состояние
      queryClient.setQueryData(["draft", id], {
        ...draft,
        items: previousItems,
      });
      setItemsOrder(previousOrder);
    }
  };

  // --- RENDER ---
  const showSpinner =
    draftQuery.isLoading ||
    (draft?.status === "PROCESSING" &&
      (!draft?.items || draft.items.length === 0));

  if (showSpinner) {
    return (
      <div style={{ textAlign: "center", padding: 50 }}>
        <Spin size="large" />
      </div>
    );
  }

  if (draftQuery.isError || !draft) {
    return <Alert type="error" message="Ошибка загрузки черновика" />;
  }

  return (
    <div style={{ paddingBottom: 60 }}>
      {/* Header */}
      <div
        style={{
          marginBottom: 12,
          display: "flex",
          alignItems: "center",
          justifyContent: "space-between",
          gap: 8,
        }}
      >
        <div
          style={{
            display: "flex",
            alignItems: "center",
            gap: 8,
            flex: 1,
            minWidth: 0,
          }}
        >
          <Button
            icon={<ArrowLeftOutlined />}
            onClick={() => navigate("/invoices")}
            size="small"
          />

          <div
            style={{
              display: "flex",
              alignItems: "center",
              gap: 6,
              flexWrap: "wrap",
            }}
          >
            <span
              style={{ fontSize: 18, fontWeight: "bold", whiteSpace: "nowrap" }}
            >
              {draft.document_number ? `№${draft.document_number}` : "Черновик"}
            </span>
            {draft.status === "PROCESSING" && <Spin size="small" />}
            {isCanceled && (
              <Tag color="red" style={{ margin: 0 }}>
                ОТМЕНЕН
              </Tag>
            )}
          </div>
        </div>

        {/* Правая часть хедера: Кнопка чека, Кнопка перетаскивания и Кнопка удаления */}
        <div style={{ display: "flex", gap: 8 }}>
          {/* Кнопка просмотра чека (только если есть URL) */}
          {draft.photo_url && (
            <Button
              icon={<FileImageOutlined />}
              onClick={() => setPreviewVisible(true)}
              size="small"
            >
              Чек
            </Button>
          )}

          {/* Кнопка переключения режима перетаскивания */}
          <Button
            type={isReordering ? "primary" : "default"}
            icon={<SwapOutlined rotate={90} />}
            onClick={() => setIsReordering(!isReordering)}
            size="small"
          >
            {isReordering ? "Ок" : ""}
          </Button>

          <Button
            danger={isCanceled}
            type={isCanceled ? "primary" : "default"}
            icon={isCanceled ? <DeleteOutlined /> : <RestOutlined />}
            onClick={handleDelete}
            loading={deleteDraftMutation.isPending}
            size="small"
          >
            {isCanceled ? "Удалить" : "Отмена"}
          </Button>
        </div>
      </div>

      {/* Form: Склады и Поставщики */}
      <div
        style={{
          background: "#fff",
          padding: 12,
          borderRadius: 8,
          marginBottom: 12,
          opacity: isCanceled ? 0.6 : 1,
        }}
      >
        <Form
          form={form}
          layout="vertical"
          initialValues={{ date_incoming: dayjs() }}
        >
          <Row gutter={10}>
            <Col span={12}>
              <Form.Item
                label="Дата"
                name="date_incoming"
                rules={[{ required: true }]}
                style={{ marginBottom: 8 }}
              >
                <DatePicker
                  style={{ width: "100%" }}
                  format="DD.MM.YYYY"
                  size="middle"
                />
              </Form.Item>
            </Col>
            <Col span={12}>
              {/* Входящий номер */}
              <Form.Item
                label="Входящий номер"
                name="incoming_document_number"
                style={{ marginBottom: 8 }}
              >
                <Input placeholder="№ Документа" size="middle" />
              </Form.Item>
            </Col>
          </Row>
          <Row gutter={10}>
            <Col span={24}>
              <Form.Item
                label="Склад"
                name="store_id"
                rules={[{ required: true, message: "Выберите склад" }]}
                style={{ marginBottom: 8 }}
              >
                <Select
                  placeholder="Куда?"
                  loading={dictQuery.isLoading}
                  options={stores.map((s) => ({ label: s.name, value: s.id }))}
                  size="middle"
                />
              </Form.Item>
            </Col>
          </Row>
          <Form.Item
            label="Поставщик"
            name="supplier_id"
            rules={[{ required: true, message: "Выберите поставщика" }]}
            style={{ marginBottom: 8 }}
          >
            <Select
              placeholder="От кого?"
              loading={dictQuery.isLoading}
              options={suppliers.map((s) => ({ label: s.name, value: s.id }))}
              size="middle"
              showSearch
              filterOption={(input, option) =>
                (option?.label ?? "")
                  .toLowerCase()
                  .includes(input.toLowerCase())
              }
            />
          </Form.Item>
          <Form.Item
            label="Комментарий"
            name="comment"
            style={{ marginBottom: 0 }}
          >
            <TextArea
              rows={1}
              placeholder="Комментарий..."
              style={{ fontSize: 13 }}
            />
          </Form.Item>
        </Form>
      </div>

      {/* Items Header */}
      <div
        style={{
          marginBottom: 8,
          display: "flex",
          justifyContent: "space-between",
          alignItems: "center",
          padding: "0 4px",
        }}
      >
        <Text strong>Позиции ({draft.items.length})</Text>
        {invalidItemsCount > 0 && (
          <Text type="danger" style={{ fontSize: 12 }}>
            {invalidItemsCount} нераспознано
          </Text>
        )}
      </div>

      {/* Items List */}
      <DragDropContext onDragStart={handleDragStart} onDragEnd={handleDragEnd}>
        <Droppable droppableId="draft-items">
          {(provided, snapshot) => (
            <div
              {...provided.droppableProps}
              ref={provided.innerRef}
              style={{
                display: "flex",
                flexDirection: "column",
                gap: 8,
                backgroundColor: snapshot.isDraggingOver
                  ? "#f0f0f0"
                  : "transparent",
                borderRadius: "4px",
                padding: snapshot.isDraggingOver ? "8px" : "0",
                transition: "background-color 0.2s ease",
              }}
            >
              {draft.items.map((item, index) => (
                <DraftItemRow
                  key={item.id}
                  item={item}
                  index={index}
                  onUpdate={handleItemUpdate}
                  onDelete={(itemId) => deleteItemMutation.mutate(itemId)}
                  isUpdating={updatingItems.has(item.id)}
                  recommendations={recommendationsQuery.data || []}
                  isReordering={isReordering}
                />
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>

      {/* Кнопка добавления позиции */}
      <Button
        type="dashed"
        block
        icon={<PlusOutlined />}
        style={{ marginTop: 12, marginBottom: 80, height: 48 }}
        onClick={() => addItemMutation.mutate()}
        loading={addItemMutation.isPending}
        disabled={isCanceled}
      >
        Добавить товар
      </Button>

      {/* Footer Actions */}
      <Affix offsetBottom={60}>
        <div
          style={{
            background: "#fff",
            padding: "8px 16px",
            borderTop: "1px solid #eee",
            boxShadow: "0 -2px 10px rgba(0,0,0,0.05)",
            display: "flex",
            justifyContent: "space-between",
            alignItems: "center",
            borderRadius: "8px 8px 0 0",
          }}
        >
          <div style={{ display: "flex", flexDirection: "column" }}>
            <span style={{ fontSize: 11, color: "#888", lineHeight: 1 }}>
              Итого:
            </span>
            <span
              style={{
                fontSize: 18,
                fontWeight: "bold",
                color: "#1890ff",
                lineHeight: 1.2,
              }}
            >
              {totalSum.toLocaleString("ru-RU", {
                style: "currency",
                currency: "RUB",
                minimumFractionDigits: 2,
                maximumFractionDigits: 2,
              })}
            </span>
          </div>

          <Button
            type="primary"
            icon={<CheckOutlined />}
            onClick={handleCommit}
            loading={commitMutation.isPending}
            disabled={invalidItemsCount > 0 || isCanceled}
            style={{ height: 40, padding: "0 24px" }}
          >
            {isCanceled ? "Восстановить" : "Отправить"}
          </Button>
        </div>
      </Affix>

      {/* Скрытый компонент для просмотра изображения */}
      {draft.photo_url && (
        <div style={{ display: "none" }}>
          <Image.PreviewGroup
            preview={{
              visible: previewVisible,
              onVisibleChange: (vis) => setPreviewVisible(vis),
              movable: true,
              scaleStep: 0.5,
            }}
          >
            <Image src={getStaticUrl(draft.photo_url)} />
          </Image.PreviewGroup>
        </div>
      )}
    </div>
  );
};
