import { useState, useEffect, useCallback } from 'react';
import { Table, Card, Input, Typography, App, Tag, Button, Space, Drawer, Select, Grid } from 'antd';
import { SearchOutlined, DownloadOutlined, RollbackOutlined } from '@ant-design/icons';
import { useOutletContext } from 'react-router-dom';
import { api } from '@/lib/api';
import type { Order, PaginationMeta, AppOutletContext, DonationPage } from '@/types/api';

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

export default function DonationsPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const isMobile = !Grid.useBreakpoint().md;
  const [donations, setDonations] = useState<Order[]>([]);
  const [pagination, setPagination] = useState<PaginationMeta>({ page: 1, limit: 20, total: 0, totalPages: 0 });
  const [loading, setLoading] = useState(false);
  const [search, setSearch] = useState('');
  const [donationPageFilter, setDonationPageFilter] = useState<string | undefined>();
  const [donationPageOptions, setDonationPageOptions] = useState<{ id: string; title: string }[]>([]);
  const [refundModalOpen, setRefundModalOpen] = useState(false);
  const [refundTarget, setRefundTarget] = useState<Order | null>(null);
  const [refundReason, setRefundReason] = useState('');
  const [refundLoading, setRefundLoading] = useState(false);
  const { message } = App.useApp();

  // Fetch donation page options for filter
  useEffect(() => {
    api.get('/payments/admin/donation-pages', { params: { limit: 100 } })
      .then(({ data }) => setDonationPageOptions(data.pages?.map((p: DonationPage) => ({ id: p.id, title: p.title })) || []))
      .catch(() => {});
  }, []);

  const fetchDonations = useCallback(async (page = 1) => {
    setLoading(true);
    try {
      const params: Record<string, string | number> = { page, limit: 20 };
      if (search) params.search = search;
      if (donationPageFilter) params.donationPageId = donationPageFilter;
      const { data } = await api.get('/payments/admin/donations', { params });
      setDonations(data.donations);
      setPagination(data.pagination);
    } catch {
      message.error('Failed to load donations');
    } finally {
      setLoading(false);
    }
  }, [search, donationPageFilter, message]);

  useEffect(() => { fetchDonations(); }, [fetchDonations]);

  useEffect(() => {
    setPageHeader({ title: 'Donation Orders' });
    return () => setPageHeader(null);
  }, [setPageHeader]);

  const handleRefund = async () => {
    if (!refundTarget) return;
    setRefundLoading(true);
    try {
      await api.post(`/payments/admin/donations/${refundTarget.id}/refund`, {
        reason: refundReason || undefined,
      });
      message.success('Donation refunded successfully');
      setRefundModalOpen(false);
      setRefundTarget(null);
      setRefundReason('');
      fetchDonations(pagination.page);
    } catch (err: unknown) {
      const msg = (err as { response?: { data?: { error?: { message?: string } } } })
        ?.response?.data?.error?.message || 'Refund failed';
      message.error(msg);
    } finally {
      setRefundLoading(false);
    }
  };

  const handleExport = async () => {
    try {
      const params: Record<string, string> = {};
      if (search) params.search = search;
      const { data } = await api.get('/payments/admin/donations/export', {
        params,
        responseType: 'blob',
      });
      const url = window.URL.createObjectURL(new Blob([data]));
      const a = document.createElement('a');
      a.href = url;
      a.download = `donations-${new Date().toISOString().slice(0, 10)}.csv`;
      a.click();
      window.URL.revokeObjectURL(url);
    } catch {
      message.error('Failed to export donations');
    }
  };

  const statusColors: Record<string, string> = {
    PENDING: 'blue',
    COMPLETED: 'green',
    FAILED: 'red',
    REFUNDED: 'orange',
  };

  const columns = [
    {
      title: 'Date',
      dataIndex: 'createdAt',
      key: 'date',
      render: (v: string) => new Date(v).toLocaleString(),
    },
    {
      title: 'Donor',
      key: 'donor',
      render: (_: unknown, r: Order) => (
        <div>
          <div>{r.isAnonymous ? 'Anonymous' : (r.buyerName || r.buyerEmail)}</div>
          {!r.isAnonymous && r.buyerName && (
            <Text type="secondary" style={{ fontSize: 12 }}>{r.buyerEmail}</Text>
          )}
        </div>
      ),
    },
    {
      title: 'Amount',
      dataIndex: 'amountCAD',
      key: 'amount',
      render: (v: number) => <Text strong>${(v / 100).toFixed(2)}</Text>,
    },
    {
      title: 'Donation Page',
      key: 'donationPage',
      render: (_: unknown, r: Order) => (
        <Text type={r.donationPage ? undefined : 'secondary'}>
          {r.donationPage?.title || 'General'}
        </Text>
      ),
      responsive: ['md'] as ('md')[],
    },
    {
      title: 'Message',
      dataIndex: 'donorMessage',
      key: 'message',
      ellipsis: true,
      render: (v: string | null) => v || <Text type="secondary">-</Text>,
      responsive: ['lg'] as ('lg')[],
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      render: (s: string) => <Tag color={statusColors[s] || 'default'}>{s}</Tag>,
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: unknown, r: Order) => (
        <Space>
          {r.status === 'COMPLETED' && (
            <Button
              size="small"
              danger
              icon={<RollbackOutlined />}
              onClick={() => {
                setRefundTarget(r);
                setRefundReason('');
                setRefundModalOpen(true);
              }}
            >
              {!isMobile && 'Refund'}
            </Button>
          )}
        </Space>
      ),
    },
  ];

  const drawerWidth = 480;
  const activeDrawerWidth = !isMobile && refundModalOpen ? drawerWidth : 0;

  return (
    <>
      <div
        style={{
          marginRight: activeDrawerWidth,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
        <Card style={{ marginBottom: 16 }}>
          <Space wrap>
            <Input
              placeholder="Search by name or email"
              prefix={<SearchOutlined />}
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              onPressEnter={() => fetchDonations(1)}
              style={{ width: 250 }}
            />
            <Select
              placeholder="Donation Page"
              allowClear
              value={donationPageFilter}
              onChange={(v) => setDonationPageFilter(v)}
              style={{ width: 200 }}
            >
              <Select.Option value="general">General (no page)</Select.Option>
              {donationPageOptions.map((p) => (
                <Select.Option key={p.id} value={p.id}>{p.title}</Select.Option>
              ))}
            </Select>
            <Button icon={<DownloadOutlined />} onClick={handleExport}>
              Export CSV
            </Button>
          </Space>
        </Card>

        <Table
          dataSource={donations}
          columns={columns}
          rowKey="id"
          loading={loading}
          scroll={{ x: 'max-content' }}
          pagination={{
            current: pagination.page,
            pageSize: pagination.limit,
            total: pagination.total,
            onChange: (p) => fetchDonations(p),
          }}
        />
      </div>

      <Drawer
        title="Refund Donation"
        open={refundModalOpen}
        onClose={() => { setRefundModalOpen(false); setRefundTarget(null); }}
        placement="right"
        width={isMobile ? '100%' : drawerWidth}
        mask={false}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        extra={
          <Button danger type="primary" loading={refundLoading} onClick={handleRefund}>
            Confirm Refund
          </Button>
        }
      >
        {refundTarget && (
          <div>
            <p><strong>Donor:</strong> {refundTarget.isAnonymous ? 'Anonymous' : (refundTarget.buyerName || refundTarget.buyerEmail)}</p>
            {!refundTarget.isAnonymous && <p><strong>Email:</strong> {refundTarget.buyerEmail}</p>}
            <p><strong>Amount:</strong> ${(refundTarget.amountCAD / 100).toFixed(2)} CAD</p>
            <p><strong>Date:</strong> {new Date(refundTarget.createdAt).toLocaleString()}</p>
            <div style={{ marginTop: 16 }}>
              <Text strong>Reason (optional):</Text>
              <TextArea
                rows={3}
                maxLength={500}
                value={refundReason}
                onChange={(e) => setRefundReason(e.target.value)}
                placeholder="Enter reason for refund..."
                style={{ marginTop: 4 }}
              />
            </div>
            <p style={{ marginTop: 12, color: '#ff4d4f', fontSize: 13 }}>
              This action will refund the donation via Stripe and cannot be undone.
            </p>
          </div>
        )}
      </Drawer>
    </>
  );
}
