import { forwardRef, useEffect, useImperativeHandle, useRef, useState } from 'react';
import { Alert, Button, Form, Input, InputNumber, Modal, Space, Typography, message } from 'antd';
import { DownOutlined, UpOutlined } from '@ant-design/icons';
import type { StorePackageItemDto } from '@dukang/shared-types';
import { STORE_PACKAGE_IMAGE_MAX_COUNT, STORE_PACKAGE_MAX_COUNT, normalizeStorePackageImageUrls } from '@dukang/shared-types';
import { request } from '../lib/api';
import PackageImagesUpload from './PackageImagesUpload';

type PackageRow = StorePackageItemDto;

export type AdminStorePackagesHandle = {
  /** 套餐已加载时写入；加载中则跳过，避免空数据覆盖线上套餐 */
  saveIfLoaded: (opts?: { quiet?: boolean }) => Promise<{ skipped: boolean }>;
};

function emptyRow(index = 0): PackageRow {
  return {
    name: '',
    price: '0',
    dishes: '',
    usableTime: '',
    otherNotes: '',
    imageUrl: '',
    imageUrls: [],
    sortOrder: index,
  };
}

const AdminStorePackagesSection = forwardRef<AdminStorePackagesHandle, { storeId: string }>(
  function AdminStorePackagesSection({ storeId }, ref) {
    const [items, setItems] = useState<PackageRow[]>([emptyRow()]);
    const [collapsed, setCollapsed] = useState<Record<number, boolean>>({});
    const [loading, setLoading] = useState(true);
    const [saving, setSaving] = useState(false);
    const itemsRef = useRef(items);
    const loadingRef = useRef(loading);

    useEffect(() => {
      itemsRef.current = items;
    }, [items]);

    useEffect(() => {
      loadingRef.current = loading;
    }, [loading]);

    useEffect(() => {
      setLoading(true);
      request<{ live: PackageRow[] }>(`/admin/stores/${storeId}/packages`)
        .then((data) => {
          setItems(
            data.live?.length
              ? data.live.map((p, i) => {
                  const imageUrls = normalizeStorePackageImageUrls(p);
                  return {
                    ...p,
                    price: String(p.price),
                    imageUrl: imageUrls[0] ?? '',
                    imageUrls,
                    sortOrder: i,
                  };
                })
              : [],
          );
        })
        .catch((e) => message.error(e instanceof Error ? e.message : '加载套餐失败'))
        .finally(() => setLoading(false));
    }, [storeId]);

    function updateAt(index: number, patch: Partial<PackageRow>) {
      setItems((prev) => prev.map((item, i) => (i === index ? { ...item, ...patch } : item)));
    }

    function addRow() {
      if (items.length >= STORE_PACKAGE_MAX_COUNT) return;
      setItems((prev) => [...prev, emptyRow(prev.length)]);
    }

    function removeAt(index: number) {
      const run = () => {
        setItems((prev) => {
          const next = prev.filter((_, i) => i !== index).map((item, i) => ({ ...item, sortOrder: i }));
          return next.length ? next : [];
        });
        setCollapsed((prev) => {
          const next: Record<number, boolean> = {};
          Object.entries(prev).forEach(([k, v]) => {
            const i = Number(k);
            if (i < index) next[i] = v;
            else if (i > index) next[i - 1] = v;
          });
          return next;
        });
      };
      if (items.length === 1) {
        Modal.confirm({
          title: '清空门店套餐',
          content: '删除最后一条套餐后，该门店将无展示套餐，确认继续？',
          okText: '确认删除',
          cancelText: '取消',
          onOk: run,
        });
        return;
      }
      run();
    }

    function toggleCollapse(index: number) {
      setCollapsed((prev) => ({ ...prev, [index]: !prev[index] }));
    }

    async function save(opts?: { quiet?: boolean }) {
      const currentItems = itemsRef.current;
      const filled = currentItems
        .map((item, index) => {
          const imageUrls = normalizeStorePackageImageUrls(item);
          return {
            name: item.name.trim(),
            price: item.price.trim(),
            dishes: item.dishes.trim(),
            usableTime: item.usableTime?.trim() || null,
            otherNotes: item.otherNotes?.trim() || null,
            imageUrl: imageUrls[0] ?? null,
            imageUrls,
            sortOrder: index,
          };
        })
        // 允许整店无套餐：忽略空白占位行（默认 price=0 不算已填）
        .filter((item) => {
          const hasText = !!(item.name || item.dishes || item.usableTime || item.otherNotes);
          const hasImages = item.imageUrls.length > 0;
          const hasNonZeroPrice = item.price !== '' && Number(item.price) !== 0;
          return hasText || hasImages || hasNonZeroPrice;
        });

      for (let i = 0; i < filled.length; i++) {
        const item = filled[i];
        if (!item.name) {
          message.warning(`第 ${i + 1} 条套餐名称不能为空`);
          throw new Error('套餐校验失败');
        }
        if (!item.dishes) {
          message.warning(`第 ${i + 1} 条套餐菜品不能为空`);
          throw new Error('套餐校验失败');
        }
        const price = Number(item.price);
        if (!Number.isFinite(price) || price < 0) {
          message.warning(`第 ${i + 1} 条套餐价格须为非负数字`);
          throw new Error('套餐校验失败');
        }
        if ((item.imageUrls?.length ?? 0) > STORE_PACKAGE_IMAGE_MAX_COUNT) {
          message.warning(`第 ${i + 1} 条套餐图片最多 ${STORE_PACKAGE_IMAGE_MAX_COUNT} 张`);
          throw new Error('套餐校验失败');
        }
      }

      setSaving(true);
      try {
        const data = await request<{ live: PackageRow[] }>(`/admin/stores/${storeId}/packages`, {
          method: 'PUT',
          body: JSON.stringify({
            packages: filled.map((p) => ({ ...p, price: Number(p.price).toFixed(2) })),
          }),
        });
        if (!opts?.quiet) message.success('套餐已保存并生效');
        setItems(
          data.live?.length
            ? data.live.map((p, i) => {
                const imageUrls = normalizeStorePackageImageUrls(p);
                return {
                  ...p,
                  price: String(p.price),
                  imageUrl: imageUrls[0] ?? '',
                  imageUrls,
                  sortOrder: i,
                };
              })
            : [],
        );
      } catch (e) {
        if (!opts?.quiet) message.error(e instanceof Error ? e.message : '保存失败');
        throw e;
      } finally {
        setSaving(false);
      }
    }

    useImperativeHandle(ref, () => ({
      saveIfLoaded: async (opts) => {
        if (loadingRef.current) return { skipped: true };
        await save(opts);
        return { skipped: false };
      },
    }));

    if (loading) {
      return <Typography.Text type="secondary">加载套餐中…</Typography.Text>;
    }

    if (!items.length) {
      return (
        <Form layout="vertical" requiredMark={false}>
          <Alert type="info" showIcon style={{ marginBottom: 16 }} message="该门店暂无套餐，可添加或保存为空。" />
          <Button onClick={addRow} style={{ marginBottom: 16 }}>
            添加套餐
          </Button>
          <Button type="primary" loading={saving} onClick={() => void save().catch(() => undefined)}>
            保存套餐
          </Button>
        </Form>
      );
    }

    return (
      <Form layout="vertical" requiredMark={false}>
        <Alert
          type="info"
          showIcon
          style={{ marginBottom: 16 }}
          message={`总部直存立即生效，无需审核。同一门店最多 ${STORE_PACKAGE_MAX_COUNT} 条套餐。`}
        />

        {items.map((item, index) => {
          const isCollapsed = !!collapsed[index];
          const displayName = item.name.trim() || `套餐 ${index + 1}`;
          return (
            <div
              key={index}
              style={{
                marginBottom: 16,
                padding: 16,
                border: '1px solid #f0f0f0',
                borderRadius: 8,
                background: '#fafafa',
              }}
            >
              <Space style={{ width: '100%', justifyContent: 'space-between', marginBottom: isCollapsed ? 0 : 12 }}>
                <Button
                  type="text"
                  icon={isCollapsed ? <DownOutlined /> : <UpOutlined />}
                  onClick={() => toggleCollapse(index)}
                  style={{ paddingLeft: 0, height: 'auto' }}
                >
                  <Typography.Title level={5} style={{ margin: 0 }}>
                    {displayName}
                  </Typography.Title>
                </Button>
                {items.length > 0 ? (
                  <Button type="link" danger onClick={() => removeAt(index)}>
                    删除
                  </Button>
                ) : null}
              </Space>

              {!isCollapsed ? (
                <>
                  <Form.Item label="套餐名称" required style={{ marginBottom: 12 }}>
                    <Input
                      placeholder="如：套餐A"
                      value={item.name}
                      onChange={(e) => updateAt(index, { name: e.target.value })}
                    />
                  </Form.Item>

                  <Form.Item label="价格（元）" required style={{ marginBottom: 12 }}>
                    <InputNumber
                      min={0}
                      precision={2}
                      style={{ width: '100%' }}
                      addonAfter="元"
                      placeholder="198"
                      value={item.price === '' ? undefined : Number(item.price)}
                      onChange={(v) => updateAt(index, { price: v != null ? String(v) : '' })}
                    />
                  </Form.Item>

                  <Form.Item label="菜品" required style={{ marginBottom: 12 }}>
                    <Input.TextArea
                      rows={2}
                      placeholder="红烧肉、红烧鱼、油焖茄子"
                      value={item.dishes}
                      onChange={(e) => updateAt(index, { dishes: e.target.value })}
                    />
                  </Form.Item>

                  <Form.Item label="使用时间" style={{ marginBottom: 12 }}>
                    <Input
                      placeholder="节假日除外"
                      value={item.usableTime || ''}
                      onChange={(e) => updateAt(index, { usableTime: e.target.value })}
                    />
                  </Form.Item>

                  <Form.Item label="套餐图片" style={{ marginBottom: 12 }}>
                    <PackageImagesUpload
                      value={normalizeStorePackageImageUrls(item)}
                      onChange={(imageUrls) =>
                        updateAt(index, {
                          imageUrls,
                          imageUrl: imageUrls[0] ?? '',
                        })
                      }
                    />
                  </Form.Item>

                  <Form.Item label="其他说明" style={{ marginBottom: 0 }}>
                    <Input
                      placeholder="不可叠加"
                      value={item.otherNotes || ''}
                      onChange={(e) => updateAt(index, { otherNotes: e.target.value })}
                    />
                  </Form.Item>
                </>
              ) : null}
            </div>
          );
        })}

        {items.length < STORE_PACKAGE_MAX_COUNT ? (
          <Button onClick={addRow} style={{ marginBottom: 16 }}>
            添加套餐
          </Button>
        ) : null}

        <Typography.Paragraph type="secondary" style={{ marginBottom: 12 }}>
          上传套餐图后请点右上角「保存修改」（会连同套餐一起保存），或点下方「保存套餐」。仅上传不保存，刷新会丢失。
        </Typography.Paragraph>

        <Button type="primary" loading={saving} onClick={() => void save().catch(() => undefined)}>
          保存套餐
        </Button>
      </Form>
    );
  },
);

export default AdminStorePackagesSection;
