import { useState, useEffect, useCallback, useMemo } from 'react';
import { useOutletContext } from 'react-router-dom';
import {
  Button, Space, Badge, Table, Form, Input, DatePicker, Drawer,
  App, Popconfirm, Typography, Tag, Tooltip, Grid, Result,
} from 'antd';
import {
  ReloadOutlined, PlusOutlined, VideoCameraOutlined,
  CopyOutlined, DeleteOutlined, LoginOutlined, LinkOutlined,
  ThunderboltOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import { api } from '@/lib/api';
import type { AppOutletContext } from '@/components/AppLayout';
import type { Meeting, ServicesStatus, ServicesConfig } from '@/types/api';
import { buildServiceUrl } from '@/lib/service-url';

const { Text, Paragraph } = Typography;

export default function JitsiMeetPage() {
  const { setPageHeader } = useOutletContext<AppOutletContext>();
  const { message } = App.useApp();
  const screens = Grid.useBreakpoint();
  const isMobile = !screens.md;

  const [meetings, setMeetings] = useState<Meeting[]>([]);
  const [loading, setLoading] = useState(true);
  const [online, setOnline] = useState<boolean | null>(null);
  const [config, setConfig] = useState<ServicesConfig | null>(null);
  const [createOpen, setCreateOpen] = useState(false);
  const [creating, setCreating] = useState(false);
  const [fastMeetLoading, setFastMeetLoading] = useState(false);
  const [form] = Form.useForm();

  const fetchStatus = useCallback(async () => {
    try {
      const [statusRes, configRes] = await Promise.all([
        api.get<ServicesStatus>('/services/status'),
        api.get<ServicesConfig>('/services/config'),
      ]);
      setOnline(statusRes.data.jitsi.online);
      setConfig(configRes.data);
    } catch {
      setOnline(false);
    }
  }, []);

  const fetchMeetings = useCallback(async () => {
    try {
      const res = await api.get<{ meetings: Meeting[] }>('/jitsi/meetings');
      setMeetings(res.data.meetings);
    } catch {
      message.error('Failed to load meetings');
    } finally {
      setLoading(false);
    }
  }, [message]);

  useEffect(() => {
    fetchStatus();
    fetchMeetings();
  }, [fetchStatus, fetchMeetings]);

  const meetUrl = config
    ? buildServiceUrl(config.jitsiSubdomain, config.domain, config.jitsiPort)
    : null;

  const handleRefresh = useCallback(() => {
    setLoading(true);
    fetchStatus();
    fetchMeetings();
  }, [fetchStatus, fetchMeetings]);

  const handleCreate = useCallback(async (values: { title: string; description?: string; schedule?: [dayjs.Dayjs, dayjs.Dayjs] }) => {
    setCreating(true);
    try {
      const body: Record<string, unknown> = { title: values.title };
      if (values.description) body.description = values.description;
      if (values.schedule) {
        body.startTime = values.schedule[0].toISOString();
        body.endTime = values.schedule[1].toISOString();
      }
      await api.post('/jitsi/meetings', body);
      message.success('Meeting created');
      setCreateOpen(false);
      form.resetFields();
      fetchMeetings();
    } catch {
      message.error('Failed to create meeting');
    } finally {
      setCreating(false);
    }
  }, [form, message, fetchMeetings]);

  const handleDelete = useCallback(async (id: string) => {
    try {
      await api.delete(`/jitsi/meetings/${id}`);
      message.success('Meeting deleted');
      fetchMeetings();
    } catch {
      message.error('Failed to delete meeting');
    }
  }, [message, fetchMeetings]);

  const handleJoinAsModerator = useCallback(async (meeting: Meeting) => {
    if (!meetUrl) return;
    try {
      const res = await api.post<{ token: string; jitsiRoom: string; domain: string }>(`/jitsi/meetings/${meeting.slug}/token`);
      const url = `${meetUrl}/${res.data.jitsiRoom}?jwt=${res.data.token}`;
      window.open(url, '_blank', 'noopener,noreferrer');
    } catch {
      message.error('Failed to generate meeting token');
    }
  }, [meetUrl, message]);

  const copyGuestLink = useCallback((meeting: Meeting) => {
    const origin = window.location.origin;
    const link = `${origin}/meet/${meeting.slug}`;
    navigator.clipboard.writeText(link);
    message.success('Guest link copied');
  }, [message]);

  const copyModeratorLink = useCallback(async (meeting: Meeting) => {
    if (!meetUrl) return;
    try {
      const res = await api.post<{ token: string; jitsiRoom: string }>(`/jitsi/meetings/${meeting.slug}/token`);
      const url = `${meetUrl}/${res.data.jitsiRoom}?jwt=${res.data.token}`;
      navigator.clipboard.writeText(url);
      message.success('Moderator link copied (expires in 2h)');
    } catch {
      message.error('Failed to generate moderator link');
    }
  }, [meetUrl, message]);

  const handleFastMeeting = useCallback(async () => {
    if (!meetUrl) {
      message.error('Jitsi service not configured');
      return;
    }
    setFastMeetLoading(true);
    try {
      const title = `Quick Meeting — ${dayjs().format('MMM D, h:mm A')}`;
      const createRes = await api.post<Meeting>('/jitsi/meetings', { title });
      const slug = createRes.data.slug;

      const tokenRes = await api.post<{ token: string; jitsiRoom: string }>(`/jitsi/meetings/${slug}/token`);

      const guestLink = `${window.location.origin}/meet/${slug}`;
      await navigator.clipboard.writeText(guestLink);

      message.success('Guest link copied — opening meeting...');
      window.open(`${meetUrl}/${tokenRes.data.jitsiRoom}?jwt=${tokenRes.data.token}`, '_blank', 'noopener,noreferrer');
      fetchMeetings();
    } catch {
      message.error('Failed to create fast meeting');
    } finally {
      setFastMeetLoading(false);
    }
  }, [meetUrl, message, fetchMeetings]);

  const headerActions = useMemo(() => (
    <Space>
      <Badge
        status={online === null ? 'processing' : online ? 'success' : 'error'}
        text={online === null ? 'Checking...' : online ? 'Online' : 'Offline'}
      />
      <Button icon={<ReloadOutlined />} onClick={handleRefresh} size="small">
        Refresh
      </Button>
      <Button icon={<ThunderboltOutlined />} onClick={handleFastMeeting} loading={fastMeetLoading} size="small">
        Fast Meeting
      </Button>
      <Button type="primary" icon={<PlusOutlined />} onClick={() => setCreateOpen(true)} size="small">
        New Meeting
      </Button>
    </Space>
  ), [online, handleRefresh, handleFastMeeting, fastMeetLoading]);

  useEffect(() => {
    setPageHeader({ title: 'Video Meet', actions: headerActions });
    return () => setPageHeader(null);
  }, [setPageHeader, headerActions]);

  if (isMobile) {
    return (
      <Result
        status="info"
        title="Desktop Required"
        subTitle="Meeting management requires a desktop browser."
        icon={<VideoCameraOutlined style={{ fontSize: 48 }} />}
      />
    );
  }

  const columns = [
    {
      title: 'Title',
      dataIndex: 'title',
      key: 'title',
      render: (title: string, record: Meeting) => (
        <Space direction="vertical" size={0}>
          <Text strong>{title}</Text>
          {record.description && (
            <Text type="secondary" style={{ fontSize: 12 }}>{record.description}</Text>
          )}
        </Space>
      ),
    },
    {
      title: 'Status',
      dataIndex: 'isActive',
      key: 'status',
      width: 100,
      render: (isActive: boolean) => (
        <Tag color={isActive ? 'green' : 'default'}>{isActive ? 'Active' : 'Ended'}</Tag>
      ),
    },
    {
      title: 'Schedule',
      key: 'schedule',
      width: 200,
      render: (_: unknown, record: Meeting) => {
        if (!record.startTime) return <Text type="secondary">Anytime</Text>;
        return (
          <Space direction="vertical" size={0}>
            <Text style={{ fontSize: 12 }}>{dayjs(record.startTime).format('MMM D, YYYY h:mm A')}</Text>
            {record.endTime && (
              <Text type="secondary" style={{ fontSize: 12 }}>to {dayjs(record.endTime).format('h:mm A')}</Text>
            )}
          </Space>
        );
      },
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      key: 'createdAt',
      width: 140,
      render: (d: string) => dayjs(d).format('MMM D, YYYY'),
    },
    {
      title: 'Actions',
      key: 'actions',
      width: 280,
      render: (_: unknown, record: Meeting) => (
        <Space size="small" wrap>
          <Tooltip title="Join as moderator">
            <Button
              size="small"
              type="primary"
              icon={<LoginOutlined />}
              onClick={() => handleJoinAsModerator(record)}
              disabled={!record.isActive}
            >
              Join
            </Button>
          </Tooltip>
          <Tooltip title="Copy guest link">
            <Button size="small" icon={<LinkOutlined />} onClick={() => copyGuestLink(record)}>
              Guest Link
            </Button>
          </Tooltip>
          <Tooltip title="Copy moderator link (JWT, expires in 2h)">
            <Button size="small" icon={<CopyOutlined />} onClick={() => copyModeratorLink(record)}>
              Mod Link
            </Button>
          </Tooltip>
          <Popconfirm
            title="Delete this meeting?"
            onConfirm={() => handleDelete(record.id)}
            okText="Delete"
            okButtonProps={{ danger: true }}
          >
            <Button size="small" danger icon={<DeleteOutlined />} />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  const drawerWidth = 480;

  return (
    <>
      <div
        style={{
          marginRight: createOpen ? drawerWidth : 0,
          transition: 'margin-right 0.15s cubic-bezier(0.2, 0, 0, 1)',
        }}
      >
        <Table
          dataSource={meetings}
          columns={columns}
          rowKey="id"
          loading={loading}
          pagination={false}
          scroll={{ x: 'max-content' }}
          locale={{ emptyText: 'No meetings yet. Create one to get started.' }}
        />
      </div>

      <Drawer
        title="Create Meeting"
        open={createOpen}
        placement="right"
        width={drawerWidth}
        mask={false}
        destroyOnHidden
        rootStyle={{ position: 'absolute', top: 64, height: 'calc(100vh - 64px)' }}
        onClose={() => { setCreateOpen(false); form.resetFields(); }}
        extra={
          <Space>
            <Button onClick={() => { setCreateOpen(false); form.resetFields(); }} disabled={creating}>
              Cancel
            </Button>
            <Button type="primary" loading={creating} onClick={() => form.submit()}>
              Create
            </Button>
          </Space>
        }
      >
        <Form form={form} layout="vertical" onFinish={handleCreate}>
          <Form.Item
            label="Title"
            name="title"
            rules={[{ required: true, message: 'Enter a meeting title' }]}
          >
            <Input placeholder="e.g. Team Standup" maxLength={200} />
          </Form.Item>
          <Form.Item label="Description" name="description">
            <Input.TextArea rows={3} placeholder="Optional description for guests" maxLength={2000} />
          </Form.Item>
          <Form.Item label="Schedule (optional)" name="schedule">
            <DatePicker.RangePicker showTime format="YYYY-MM-DD HH:mm" style={{ width: '100%' }} />
          </Form.Item>
        </Form>
        <Paragraph type="secondary" style={{ fontSize: 12 }}>
          A unique guest link will be generated. Share it with anyone — they can join without an account.
          Authenticated users join as moderators with full meeting controls.
        </Paragraph>
      </Drawer>
    </>
  );
}
