import { useState, useEffect, useCallback } from 'react';
import {
  Table,
  Button,
  Input,
  Select,
  Tag,
  Space,
  Form,
  Switch,
  Popconfirm,
  message,
  Typography,
  Row,
  Col,
  DatePicker,
  Drawer,
  Tooltip,
  Grid,
} from 'antd';
import {
  PlusOutlined,
  DeleteOutlined,
  SearchOutlined,
  EditOutlined,
  CheckSquareOutlined,
  UserOutlined,
} from '@ant-design/icons';
import type { ColumnsType } from 'antd/es/table';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import type {
  ActionItem,
  ActionItemsListResponse,
  ActionItemStatus,
  ActionItemPriority,
  User,
} from '@/types/api';
import {
  ACTION_ITEM_STATUS_COLORS,
  ACTION_ITEM_STATUS_LABELS,
  ACTION_ITEM_PRIORITY_COLORS,
} from '@/types/api';

const { Text, Title } = Typography;

const PRIORITY_OPTIONS: { value: ActionItemPriority; label: string }[] = [
  { value: 'low', label: 'Low' },
  { value: 'normal', label: 'Normal' },
  { value: 'high', label: 'High' },
  { value: 'urgent', label: 'Urgent' },
];

const STATUS_OPTIONS: { value: ActionItemStatus; label: string }[] = [
  { value: 'open', label: 'Open' },
  { value: 'in_progress', label: 'In Progress' },
  { value: 'done', label: 'Done' },
  { value: 'blocked', label: 'Blocked' },
];

export default function ActionItemsPage() {
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;
  const [items, setItems] = useState<ActionItem[]>([]);
  const [pagination, setPagination] = useState({ page: 1, limit: 20, total: 0 });
  const [loading, setLoading] = useState(false);
  const [search, setSearch] = useState('');
  const [statusFilter, setStatusFilter] = useState<ActionItemStatus | undefined>();
  const [assigneeFilter, setAssigneeFilter] = useState<string | undefined>();
  const [overdueOnly, setOverdueOnly] = useState(false);
  const [myItemsMode, setMyItemsMode] = useState(false);

  // User search for filters
  const [userOptions, setUserOptions] = useState<{ value: string; label: string }[]>([]);
  const [userSearchLoading, setUserSearchLoading] = useState(false);

  // Drawer state
  const [drawerOpen, setDrawerOpen] = useState(false);
  const [editingItem, setEditingItem] = useState<ActionItem | null>(null);
  const [form] = Form.useForm();
  const [saving, setSaving] = useState(false);

  // User search for form assignee
  const [formUserOptions, setFormUserOptions] = useState<{ value: string; label: string }[]>([]);
  const [formUserSearchLoading, setFormUserSearchLoading] = useState(false);

  const drawerWidth = 500;

  const fetchItems = useCallback(async () => {
    setLoading(true);
    try {
      const endpoint = myItemsMode ? '/meetings/action-items/mine' : '/meetings/action-items';
      const params: Record<string, any> = { page: pagination.page, limit: pagination.limit };
      if (search) params.search = search;
      if (statusFilter) params.status = statusFilter;
      if (assigneeFilter && !myItemsMode) params.assigneeUserId = assigneeFilter;
      if (overdueOnly) params.overdue = true;
      const { data } = await api.get<ActionItemsListResponse>(endpoint, { params });
      setItems(data.actionItems);
      setPagination((p) => ({ ...p, total: data.pagination.total }));
    } catch {
      message.error('Failed to load action items');
    } finally {
      setLoading(false);
    }
  }, [pagination.page, pagination.limit, search, statusFilter, assigneeFilter, overdueOnly, myItemsMode]);

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

  const searchUsers = async (searchText: string, setOptions: typeof setUserOptions, setLoading: typeof setUserSearchLoading) => {
    if (!searchText || searchText.length < 2) return;
    setLoading(true);
    try {
      const { data } = await api.get<{ users: User[] }>('/users', { params: { search: searchText, limit: 50 } });
      setOptions(data.users.map((u) => ({ value: u.id, label: u.name || u.email })));
    } catch {
      // silently fail
    } finally {
      setLoading(false);
    }
  };

  const openCreate = () => {
    setEditingItem(null);
    form.resetFields();
    form.setFieldsValue({ priority: 'normal' });
    setFormUserOptions([]);
    setDrawerOpen(true);
  };

  const openEdit = (item: ActionItem) => {
    setEditingItem(item);
    form.setFieldsValue({
      title: item.title,
      description: item.description || '',
      assigneeUserId: item.assigneeUserId || undefined,
      dueDate: item.dueDate ? dayjs(item.dueDate) : null,
      priority: item.priority,
      status: item.status,
      agendaId: item.agendaId || undefined,
    });
    // Pre-populate assignee option if exists
    if (item.assignee) {
      setFormUserOptions([{ value: item.assignee.id, label: item.assignee.name || item.assignee.email }]);
    } else {
      setFormUserOptions([]);
    }
    setDrawerOpen(true);
  };

  const handleSave = async (values: any) => {
    setSaving(true);
    try {
      const payload: Record<string, any> = {
        title: values.title,
        description: values.description || null,
        assigneeUserId: values.assigneeUserId || null,
        dueDate: values.dueDate?.toISOString() || null,
        priority: values.priority,
      };

      if (editingItem) {
        payload.status = values.status;
        await api.put(`/meetings/action-items/${editingItem.id}`, payload);
        message.success('Action item updated');
      } else {
        if (values.agendaId) payload.agendaId = values.agendaId;
        await api.post('/meetings/action-items', payload);
        message.success('Action item created');
      }

      setDrawerOpen(false);
      setEditingItem(null);
      form.resetFields();
      fetchItems();
    } catch {
      message.error(editingItem ? 'Failed to update action item' : 'Failed to create action item');
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async (id: string) => {
    try {
      await api.delete(`/meetings/action-items/${id}`);
      message.success('Action item deleted');
      fetchItems();
    } catch {
      message.error('Failed to delete action item');
    }
  };

  const isOverdue = (item: ActionItem) => {
    return item.dueDate && item.status !== 'done' && dayjs(item.dueDate).isBefore(dayjs(), 'day');
  };

  const columns: ColumnsType<ActionItem> = [
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      render: (title: string, record) => (
        <Button type="link" onClick={() => openEdit(record)} style={{ padding: 0 }}>
          {title}
        </Button>
      ),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 110,
      render: (status: ActionItemStatus) => (
        <Tag color={ACTION_ITEM_STATUS_COLORS[status]}>{ACTION_ITEM_STATUS_LABELS[status]}</Tag>
      ),
    },
    {
      title: 'Priority',
      dataIndex: 'priority',
      key: 'priority',
      width: 90,
      render: (priority: ActionItemPriority) => (
        <Tag color={ACTION_ITEM_PRIORITY_COLORS[priority]}>
          {priority.charAt(0).toUpperCase() + priority.slice(1)}
        </Tag>
      ),
    },
    {
      title: 'Assignee',
      key: 'assignee',
      width: 140,
      render: (_, record) => (
        <Text>{record.assignee?.name || record.assignee?.email || '—'}</Text>
      ),
      responsive: ['md'],
    },
    {
      title: 'Due Date',
      dataIndex: 'dueDate',
      key: 'dueDate',
      width: 120,
      render: (date: string | null, record) => {
        if (!date) return <Text type="secondary">—</Text>;
        const overdue = isOverdue(record);
        return (
          <Text style={overdue ? { color: '#ff4d4f', fontWeight: 600 } : undefined}>
            {dayjs(date).format('MMM D, YYYY')}
          </Text>
        );
      },
    },
    {
      title: 'Meeting',
      key: 'agenda',
      width: 160,
      render: (_, record) => (
        record.agenda ? (
          <Text type="secondary" ellipsis style={{ maxWidth: 140 }}>
            {record.agenda.title}
          </Text>
        ) : (
          <Text type="secondary">—</Text>
        )
      ),
      responsive: ['lg'],
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 100,
      render: (_, record) => (
        <Space size="small">
          <Tooltip title="Edit">
            <Button size="small" icon={<EditOutlined />} onClick={() => openEdit(record)} />
          </Tooltip>
          <Popconfirm title="Delete this action item?" onConfirm={() => handleDelete(record.id)}>
            <Button size="small" danger icon={<DeleteOutlined />} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div style={{ padding: screens.md ? 24 : 16 }}>
      <div
        style={{
          marginRight: isMobile ? 0 : drawerOpen ? drawerWidth : 0,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
        <Row justify="space-between" align="middle" style={{ marginBottom: 16 }}>
          <Col>
            <Title level={4} style={{ margin: 0 }}>
              <CheckSquareOutlined style={{ marginRight: 8 }} />
              Action Items
            </Title>
          </Col>
          <Col>
            <Button type="primary" icon={<PlusOutlined />} onClick={openCreate}>
              {screens.md ? 'New Action Item' : 'New'}
            </Button>
          </Col>
        </Row>

        {/* Filters */}
        <Row gutter={[12, 12]} style={{ marginBottom: 16 }}>
          <Col xs={24} sm={12} md={6}>
            <Input
              placeholder="Search action items..."
              prefix={<SearchOutlined />}
              value={search}
              onChange={(e) => setSearch(e.target.value)}
              allowClear
            />
          </Col>
          <Col xs={12} sm={6} md={4}>
            <Select
              placeholder="Status"
              style={{ width: '100%' }}
              allowClear
              value={statusFilter}
              onChange={setStatusFilter}
              options={STATUS_OPTIONS}
            />
          </Col>
          <Col xs={12} sm={6} md={5}>
            <Select
              placeholder="Assignee"
              style={{ width: '100%' }}
              allowClear
              showSearch
              filterOption={false}
              value={assigneeFilter}
              onChange={setAssigneeFilter}
              onSearch={(v) => searchUsers(v, setUserOptions, setUserSearchLoading)}
              loading={userSearchLoading}
              options={userOptions}
              notFoundContent={userSearchLoading ? 'Searching...' : null}
            />
          </Col>
          <Col>
            <Space>
              <Switch
                checked={overdueOnly}
                onChange={setOverdueOnly}
                checkedChildren="Overdue"
                unCheckedChildren="All"
              />
              <Button
                type={myItemsMode ? 'primary' : 'default'}
                icon={<UserOutlined />}
                onClick={() => setMyItemsMode(!myItemsMode)}
              >
                {screens.md ? 'My Items' : 'Mine'}
              </Button>
            </Space>
          </Col>
        </Row>

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

      {/* Create / Edit Drawer */}
      <Drawer
        title={editingItem ? 'Edit Action Item' : 'New Action Item'}
        open={drawerOpen}
        onClose={() => { setDrawerOpen(false); setEditingItem(null); form.resetFields(); }}
        width={isMobile ? '100%' : drawerWidth}
        mask={false}
        destroyOnHidden
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        extra={
          <Space>
            <Button onClick={() => { setDrawerOpen(false); setEditingItem(null); form.resetFields(); }} disabled={saving}>
              Cancel
            </Button>
            <Button type="primary" loading={saving} onClick={() => form.submit()}>
              {editingItem ? 'Save' : 'Create'}
            </Button>
          </Space>
        }
      >
        <Form
          form={form}
          layout="vertical"
          onFinish={handleSave}
          initialValues={{ priority: 'normal' }}
        >
          <Form.Item name="title" label="Title" rules={[{ required: true, message: 'Title is required' }]}>
            <Input placeholder="What needs to be done?" />
          </Form.Item>
          <Form.Item name="description" label="Description">
            <Input.TextArea rows={3} placeholder="Additional details..." />
          </Form.Item>
          <Form.Item name="assigneeUserId" label="Assignee">
            <Select
              placeholder="Search for a user..."
              allowClear
              showSearch
              filterOption={false}
              onSearch={(v) => searchUsers(v, setFormUserOptions, setFormUserSearchLoading)}
              loading={formUserSearchLoading}
              options={formUserOptions}
              notFoundContent={formUserSearchLoading ? 'Searching...' : null}
            />
          </Form.Item>
          <Form.Item name="dueDate" label="Due Date">
            <DatePicker style={{ width: '100%' }} format="YYYY-MM-DD" />
          </Form.Item>
          <Form.Item name="priority" label="Priority">
            <Select options={PRIORITY_OPTIONS} />
          </Form.Item>
          {editingItem && (
            <Form.Item name="status" label="Status">
              <Select options={STATUS_OPTIONS} />
            </Form.Item>
          )}
          {!editingItem && (
            <Form.Item name="agendaId" label="Meeting (optional)">
              <Input placeholder="Agenda ID (optional)" />
            </Form.Item>
          )}
        </Form>
      </Drawer>
    </div>
  );
}
