import { useState, useEffect, useCallback } from 'react';
import {
  Table,
  Button,
  Tag,
  Space,
  Drawer,
  Form,
  Input,
  Select,
  InputNumber,
  DatePicker,
  Popconfirm,
  Tabs,
  App,
} from 'antd';
import {
  PlusOutlined,
  EditOutlined,
  DeleteOutlined,
  PlayCircleOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  ReloadOutlined,
} from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import { useMobile } from '@/hooks/useMobile';
import { METRIC_MAP, STATUS_COLORS } from '@/components/social/ChallengeCard';
import type { PaginationMeta } from '@/types/api';
import axios from 'axios';
import { getErrorMessage } from '@/utils/getErrorMessage';

const { TextArea } = Input;
const { RangePicker } = DatePicker;

interface ChallengeRow {
  id: string;
  title: string;
  description: string | null;
  metric: string;
  status: string;
  startsAt: string;
  endsAt: string;
  minTeamSize: number;
  maxTeamSize: number;
  maxTeams: number | null;
  _count?: { teams: number };
}

const METRIC_OPTIONS = Object.entries(METRIC_MAP).map(([value, info]) => ({
  value,
  label: info.label,
}));

const STATUS_TABS = ['ALL', 'DRAFT', 'UPCOMING', 'ACTIVE', 'COMPLETED', 'CANCELLED'];

export default function ChallengesAdminPage() {
  const { message } = App.useApp();
  const { isMobile } = useMobile();
  const [challenges, setChallenges] = useState<ChallengeRow[]>([]);
  const [pagination, setPagination] = useState<PaginationMeta | null>(null);
  const [loading, setLoading] = useState(true);
  const [page, setPage] = useState(1);
  const [statusFilter, setStatusFilter] = useState<string>('ALL');

  const [modalOpen, setModalOpen] = useState(false);
  const [editingId, setEditingId] = useState<string | null>(null);
  const [saving, setSaving] = useState(false);
  const [form] = Form.useForm();

  const load = useCallback(async () => {
    setLoading(true);
    try {
      const params: Record<string, unknown> = { page, limit: 20 };
      if (statusFilter !== 'ALL') params.status = statusFilter;
      const res = await api.get('/social/challenges', { params });
      setChallenges(res.data.challenges);
      setPagination(res.data.pagination);
    } catch {
      message.error('Failed to load challenges');
    } finally {
      setLoading(false);
    }
  }, [page, statusFilter]); // eslint-disable-line react-hooks/exhaustive-deps

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

  const openCreate = () => {
    setEditingId(null);
    form.resetFields();
    setModalOpen(true);
  };

  const openEdit = (row: ChallengeRow) => {
    setEditingId(row.id);
    form.setFieldsValue({
      title: row.title,
      description: row.description,
      metric: row.metric,
      dateRange: [dayjs(row.startsAt), dayjs(row.endsAt)],
      minTeamSize: row.minTeamSize,
      maxTeamSize: row.maxTeamSize,
      maxTeams: row.maxTeams,
    });
    setModalOpen(true);
  };

  const handleSave = async () => {
    try {
      const values = await form.validateFields();
      setSaving(true);

      const payload = {
        title: values.title,
        description: values.description || undefined,
        metric: values.metric,
        startsAt: values.dateRange[0].toISOString(),
        endsAt: values.dateRange[1].toISOString(),
        minTeamSize: values.minTeamSize,
        maxTeamSize: values.maxTeamSize,
        maxTeams: values.maxTeams || undefined,
      };

      if (editingId) {
        await api.put(`/social/challenges/admin/${editingId}`, payload);
        message.success('Challenge updated');
      } else {
        await api.post('/social/challenges/admin', payload);
        message.success('Challenge created');
      }
      setModalOpen(false);
      load();
    } catch (err: unknown) {
      if (axios.isAxiosError(err) && err.response?.data?.error?.message) {
        message.error(err.response.data.error.message);
      }
    } finally {
      setSaving(false);
    }
  };

  const handleAction = async (id: string, action: string) => {
    try {
      if (action === 'delete') {
        await api.delete(`/social/challenges/admin/${id}`);
        message.success('Deleted');
      } else {
        await api.post(`/social/challenges/admin/${id}/${action}`);
        message.success(`Challenge ${action}d`);
      }
      load();
    } catch (err: unknown) {
      message.error(getErrorMessage(err, `Failed to ${action}`));
    }
  };

  const columns: ColumnsType<ChallengeRow> = [
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      ellipsis: true,
    },
    {
      title: 'Metric',
      dataIndex: 'metric',
      key: 'metric',
      width: 160,
      responsive: ['md'] as any,
      render: (m: string) => {
        const info = METRIC_MAP[m];
        return info ? <Tag icon={info.icon} color={info.color}>{info.label}</Tag> : m;
      },
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 110,
      render: (s: string) => <Tag color={STATUS_COLORS[s]}>{s}</Tag>,
    },
    {
      title: 'Period',
      key: 'period',
      width: 180,
      responsive: ['md'] as any,
      render: (_: unknown, r: ChallengeRow) =>
        `${dayjs(r.startsAt).format('MMM D')} - ${dayjs(r.endsAt).format('MMM D')}`,
    },
    {
      title: 'Teams',
      key: 'teams',
      width: 70,
      responsive: ['lg'] as any,
      render: (_: unknown, r: ChallengeRow) => r._count?.teams ?? 0,
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 200,
      render: (_: unknown, r: ChallengeRow) => (
        <Space size={4} wrap>
          {r.status === 'DRAFT' && (
            <Button size="small" icon={<PlayCircleOutlined />} onClick={() => handleAction(r.id, 'activate')}>
              {!isMobile && 'Activate'}
            </Button>
          )}
          {r.status === 'ACTIVE' && (
            <>
              <Button size="small" icon={<CheckCircleOutlined />} onClick={() => handleAction(r.id, 'complete')}>
                {!isMobile && 'Complete'}
              </Button>
              <Button size="small" icon={<ReloadOutlined />} onClick={() => handleAction(r.id, 'rescore')}>
                {!isMobile && 'Rescore'}
              </Button>
            </>
          )}
          {(r.status === 'DRAFT' || r.status === 'UPCOMING') && (
            <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(r)}>{!isMobile && 'Edit'}</Button>
          )}
          {r.status !== 'COMPLETED' && r.status !== 'CANCELLED' && (
            <Popconfirm title="Cancel this challenge?" onConfirm={() => handleAction(r.id, 'cancel')}>
              <Button size="small" danger icon={<CloseCircleOutlined />}>{!isMobile && 'Cancel'}</Button>
            </Popconfirm>
          )}
          {(r.status === 'DRAFT' || r.status === 'CANCELLED') && (
            <Popconfirm title="Delete this challenge?" onConfirm={() => handleAction(r.id, 'delete')}>
              <Button size="small" danger icon={<DeleteOutlined />} />
            </Popconfirm>
          )}
        </Space>
      ),
    },
  ];

  const drawerWidth = 520;
  const activeDrawerWidth = !isMobile && modalOpen ? drawerWidth : 0;

  return (
    <>
      <div
        style={{
          marginRight: activeDrawerWidth,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: isMobile ? 'stretch' : 'center', marginBottom: 16, flexDirection: isMobile ? 'column' : 'row', gap: isMobile ? 8 : 0 }}>
          <Tabs
            activeKey={statusFilter}
            onChange={(key) => { setStatusFilter(key); setPage(1); }}
            items={STATUS_TABS.map((s) => ({ key: s, label: s === 'ALL' ? 'All' : s }))}
            size={isMobile ? 'small' : 'middle'}
            style={{ marginBottom: 0 }}
          />
          <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
            New Challenge
          </Button>
        </div>

        <Table
          dataSource={challenges}
          columns={columns}
          scroll={{ x: 'max-content' }}
          rowKey="id"
          size="small"
          loading={loading}
          pagination={{
            current: page,
            total: pagination?.total ?? 0,
            pageSize: 20,
            showSizeChanger: false,
            onChange: setPage,
          }}
        />
      </div>

      <Drawer
        title={editingId ? 'Edit Challenge' : 'New Challenge'}
        open={modalOpen}
        onClose={() => setModalOpen(false)}
        placement="right"
        width={isMobile ? '100%' : drawerWidth}
        mask={false}
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        destroyOnHidden
        extra={
          <Button type="primary" loading={saving} onClick={handleSave}>
            {editingId ? 'Save' : 'Create'}
          </Button>
        }
      >
        <Form form={form} layout="vertical">
          <Form.Item name="title" label="Title" rules={[{ required: true, max: 200 }]}>
            <Input maxLength={200} />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <TextArea rows={3} maxLength={2000} />
          </Form.Item>
          <Form.Item name="metric" label="Metric" rules={[{ required: true }]}>
            <Select options={METRIC_OPTIONS} placeholder="Select metric" />
          </Form.Item>
          <Form.Item name="dateRange" label="Date Range" rules={[{ required: true }]}>
            <RangePicker showTime style={{ width: '100%' }} />
          </Form.Item>
          <Space>
            <Form.Item name="minTeamSize" label="Min Team Size" initialValue={2}>
              <InputNumber min={1} max={50} />
            </Form.Item>
            <Form.Item name="maxTeamSize" label="Max Team Size" initialValue={10}>
              <InputNumber min={2} max={100} />
            </Form.Item>
            <Form.Item name="maxTeams" label="Max Teams">
              <InputNumber min={1} placeholder="Unlimited" />
            </Form.Item>
          </Space>
        </Form>
      </Drawer>
    </>
  );
}
