import { useState, useEffect, useRef, useCallback } from 'react';
import {
  Table,
  Tag,
  Button,
  Space,
  Input,
  Select,
  Popconfirm,
  message,
  Drawer,
  Descriptions,
  Row,
  Col,
  Grid,
} from 'antd';
import {
  CheckCircleOutlined,
  CloseCircleOutlined,
  DeleteOutlined,
  MailOutlined,
  SafetyCertificateOutlined,
  SearchOutlined,
  ReloadOutlined,
} from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import { useOutletContext } from 'react-router-dom';
import { api } from '@/lib/api';
import type { AppOutletContext } from '@/components/AppLayout';
import type {
  RepresentativeResponse,
  ResponsesListResponse,
  ResponseStatus,
  CampaignsListResponse,
  Campaign,
  PaginationMeta,
} from '@/types/api';
import {
  RESPONSE_TYPE_LABELS,
  RESPONSE_STATUS_COLORS,
  GOVERNMENT_LEVEL_COLORS,
  GOVERNMENT_LEVEL_LABELS,
} from '@/types/api';
import dayjs from 'dayjs';

export default function ResponsesPage() {
  const [responses, setResponses] = useState<RepresentativeResponse[]>([]);
  const [pagination, setPagination] = useState<PaginationMeta>({ page: 1, limit: 20, total: 0, totalPages: 0 });
  const [loading, setLoading] = useState(false);
  const [actionLoading, setActionLoading] = useState<string | null>(null);
  const [statusFilter, setStatusFilter] = useState<ResponseStatus | undefined>();
  const [campaignFilter, setCampaignFilter] = useState<string | undefined>();
  const [search, setSearch] = useState('');
  const [campaigns, setCampaigns] = useState<Campaign[]>([]);
  const [detailResponse, setDetailResponse] = useState<RepresentativeResponse | null>(null);
  const searchTimerRef = useRef<ReturnType<typeof setTimeout>>(undefined);
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  const fetchResponses = useCallback(async (page = 1) => {
    setLoading(true);
    try {
      const params: Record<string, string | number> = { page, limit: 20 };
      if (statusFilter) params.status = statusFilter;
      if (campaignFilter) params.campaignId = campaignFilter;
      if (search) params.search = search;

      const { data } = await api.get<ResponsesListResponse>('/responses', { params });
      setResponses(data.responses);
      setPagination(data.pagination);
    } catch {
      message.error('Failed to load responses');
    } finally {
      setLoading(false);
    }
  }, [statusFilter, campaignFilter, search]);

  const fetchCampaigns = async () => {
    try {
      const { data } = await api.get<CampaignsListResponse>('/campaigns', { params: { limit: 100 } });
      setCampaigns(data.campaigns);
    } catch {
      // Non-critical
    }
  };

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

  useEffect(() => {
    fetchResponses(1);
  }, [fetchResponses]);

  const handleSearch = (value: string) => {
    if (searchTimerRef.current) clearTimeout(searchTimerRef.current);
    searchTimerRef.current = setTimeout(() => {
      setSearch(value);
    }, 400);
  };

  const handleApprove = async (id: string) => {
    setActionLoading(id);
    try {
      await api.patch(`/responses/${id}/status`, { status: 'APPROVED' });
      message.success('Response approved');
      fetchResponses(pagination.page);
    } catch {
      message.error('Failed to approve response');
    } finally {
      setActionLoading(null);
    }
  };

  const handleReject = async (id: string) => {
    setActionLoading(id);
    try {
      await api.patch(`/responses/${id}/status`, { status: 'REJECTED' });
      message.success('Response rejected');
      fetchResponses(pagination.page);
    } catch {
      message.error('Failed to reject response');
    } finally {
      setActionLoading(null);
    }
  };

  const handleResendVerification = async (id: string) => {
    setActionLoading(id);
    try {
      await api.post(`/responses/${id}/resend-verification`);
      message.success('Verification email sent');
    } catch {
      message.error('Failed to send verification email');
    } finally {
      setActionLoading(null);
    }
  };

  const handleDelete = async (id: string) => {
    setActionLoading(id);
    try {
      await api.delete(`/responses/${id}`);
      message.success('Response deleted');
      fetchResponses(pagination.page);
    } catch {
      message.error('Failed to delete response');
    } finally {
      setActionLoading(null);
    }
  };

  const columns: ColumnsType<RepresentativeResponse> = [
    {
      title: 'Representative',
      dataIndex: 'representativeName',
      key: 'representativeName',
      ellipsis: true,
    },
    {
      title: 'Level',
      dataIndex: 'representativeLevel',
      key: 'level',
      width: 120,
      render: (level) => (
        <Tag color={GOVERNMENT_LEVEL_COLORS[level as keyof typeof GOVERNMENT_LEVEL_COLORS]}>
          {GOVERNMENT_LEVEL_LABELS[level as keyof typeof GOVERNMENT_LEVEL_LABELS]}
        </Tag>
      ),
    },
    {
      title: 'Type',
      dataIndex: 'responseType',
      key: 'type',
      width: 110,
      render: (type) => <Tag>{RESPONSE_TYPE_LABELS[type as keyof typeof RESPONSE_TYPE_LABELS]}</Tag>,
    },
    {
      title: 'Campaign',
      key: 'campaign',
      width: 160,
      ellipsis: true,
      render: (_, record) => record.campaign?.title || '—',
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 100,
      render: (status) => (
        <Tag color={RESPONSE_STATUS_COLORS[status as keyof typeof RESPONSE_STATUS_COLORS]}>
          {status}
        </Tag>
      ),
    },
    {
      title: 'Verified',
      key: 'verified',
      width: 80,
      align: 'center',
      responsive: ['md'] as any,
      render: (_, record) =>
        record.isVerified ? (
          <SafetyCertificateOutlined style={{ color: '#16a34a', fontSize: 16 }} />
        ) : null,
    },
    {
      title: 'Upvotes',
      dataIndex: 'upvoteCount',
      key: 'upvotes',
      width: 80,
      align: 'center',
      responsive: ['md'] as any,
    },
    {
      title: 'Submitted',
      dataIndex: 'createdAt',
      key: 'createdAt',
      width: 120,
      responsive: ['sm'] as any,
      render: (date) => dayjs(date).format('MMM D, YYYY'),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 200,
      render: (_, record) => (
        <Space size="small" wrap>
          {record.status !== 'APPROVED' && (
            <Button
              size="small"
              type="link"
              icon={<CheckCircleOutlined />}
              style={{ color: '#16a34a' }}
              loading={actionLoading === record.id}
              onClick={() => handleApprove(record.id)}
            >
              Approve
            </Button>
          )}
          {record.status !== 'REJECTED' && (
            <Button
              size="small"
              type="link"
              icon={<CloseCircleOutlined />}
              danger
              loading={actionLoading === record.id}
              onClick={() => handleReject(record.id)}
            >
              Reject
            </Button>
          )}
          {record.representativeEmail && (
            <Button
              size="small"
              type="link"
              icon={<MailOutlined />}
              loading={actionLoading === record.id}
              onClick={() => handleResendVerification(record.id)}
            >
              Verify
            </Button>
          )}
          <Popconfirm title="Delete this response?" onConfirm={() => handleDelete(record.id)}>
            <Button size="small" type="link" icon={<DeleteOutlined />} danger loading={actionLoading === record.id} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const { setPageHeader } = useOutletContext<AppOutletContext>();

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

  return (
    <>
      <Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
        <Col xs={24} sm={8}>
          <Input
            placeholder="Search responses..."
            prefix={<SearchOutlined />}
            onChange={(e) => handleSearch(e.target.value)}
            allowClear
          />
        </Col>
        <Col xs={12} sm={5}>
          <Select
            placeholder="Status"
            allowClear
            style={{ width: '100%' }}
            value={statusFilter}
            onChange={(v) => setStatusFilter(v)}
            options={[
              { value: 'PENDING', label: 'Pending' },
              { value: 'APPROVED', label: 'Approved' },
              { value: 'REJECTED', label: 'Rejected' },
            ]}
          />
        </Col>
        <Col xs={12} sm={7}>
          <Select
            placeholder="Campaign"
            allowClear
            style={{ width: '100%' }}
            value={campaignFilter}
            onChange={(v) => setCampaignFilter(v)}
            options={campaigns.map((c) => ({ value: c.id, label: c.title }))}
            showSearch
            filterOption={(input, option) =>
              (option?.label as string)?.toLowerCase().includes(input.toLowerCase())
            }
          />
        </Col>
        <Col>
          <Button icon={<ReloadOutlined />} onClick={() => fetchResponses(pagination.page)}>
            Refresh
          </Button>
        </Col>
      </Row>

      <Table
        columns={columns}
        dataSource={responses}
        rowKey="id"
        loading={loading}
        scroll={{ x: 'max-content' }}
        onRow={(record) => ({
          onClick: () => setDetailResponse(record),
          style: { cursor: 'pointer' },
        })}
        pagination={{
          current: pagination.page,
          pageSize: pagination.limit,
          total: pagination.total,
          showSizeChanger: false,
          onChange: (page) => fetchResponses(page),
        }}
        locale={{ emptyText: (search || statusFilter || campaignFilter)
          ? 'No responses match your filters.'
          : 'No responses yet. Responses appear when participants submit them through campaigns.'
        }}
      />

      <Drawer
        title="Response Details"
        open={!!detailResponse}
        onClose={() => setDetailResponse(null)}
        width={isMobile ? '100%' : 520}
        destroyOnClose
      >
        {detailResponse && (
          <Descriptions column={1} bordered size="small">
            <Descriptions.Item label="Representative">
              {detailResponse.representativeName}
              {detailResponse.representativeTitle && ` — ${detailResponse.representativeTitle}`}
            </Descriptions.Item>
            <Descriptions.Item label="Level">
              <Tag color={GOVERNMENT_LEVEL_COLORS[detailResponse.representativeLevel]}>
                {GOVERNMENT_LEVEL_LABELS[detailResponse.representativeLevel]}
              </Tag>
            </Descriptions.Item>
            <Descriptions.Item label="Type">
              <Tag>{RESPONSE_TYPE_LABELS[detailResponse.responseType]}</Tag>
            </Descriptions.Item>
            <Descriptions.Item label="Campaign">{detailResponse.campaign?.title || '—'}</Descriptions.Item>
            <Descriptions.Item label="Status">
              <Tag color={RESPONSE_STATUS_COLORS[detailResponse.status]}>{detailResponse.status}</Tag>
            </Descriptions.Item>
            <Descriptions.Item label="Verified">
              {detailResponse.isVerified ? (
                <Space>
                  <SafetyCertificateOutlined style={{ color: '#16a34a' }} />
                  {detailResponse.verifiedBy && `by ${detailResponse.verifiedBy}`}
                  {detailResponse.verifiedAt && ` on ${dayjs(detailResponse.verifiedAt).format('MMM D, YYYY')}`}
                </Space>
              ) : 'No'}
            </Descriptions.Item>
            <Descriptions.Item label="Upvotes">{detailResponse.upvoteCount}</Descriptions.Item>
            <Descriptions.Item label="Response Text">
              <div style={{ whiteSpace: 'pre-wrap', maxHeight: 300, overflow: 'auto' }}>
                {detailResponse.responseText}
              </div>
            </Descriptions.Item>
            {detailResponse.userComment && (
              <Descriptions.Item label="User Comment">
                <div style={{ whiteSpace: 'pre-wrap' }}>{detailResponse.userComment}</div>
              </Descriptions.Item>
            )}
            <Descriptions.Item label="Submitted By">
              {detailResponse.isAnonymous
                ? 'Anonymous'
                : `${detailResponse.submittedByName || '—'} (${detailResponse.submittedByEmail || '—'})`}
            </Descriptions.Item>
            <Descriptions.Item label="Submitted">
              {dayjs(detailResponse.createdAt).format('MMM D, YYYY h:mm A')}
            </Descriptions.Item>
          </Descriptions>
        )}
      </Drawer>
    </>
  );
}
