import { useState, useEffect, useCallback } from 'react';
import {
  Drawer,
  Form,
  Select,
  Switch,
  Button,
  Input,
  InputNumber,
  Table,
  Tag,
  Space,
  Typography,
  Divider,
  Tooltip,
  message,
  Alert,
} from 'antd';
import type { ColumnsType } from 'antd/es/table';
import {
  ShareAltOutlined,
  CopyOutlined,
  StopOutlined,
  LinkOutlined,
  ClockCircleOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
} from '@ant-design/icons';
import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime';
import { api } from '@/lib/api';

dayjs.extend(relativeTime);

const { Text, Paragraph } = Typography;

interface DocSharePanelProps {
  open: boolean;
  onClose: () => void;
  documentPath: string | null;
}

interface ShareLink {
  id: string;
  documentPath: string;
  shareToken: string;
  status: 'ACTIVE' | 'REVOKED' | 'EXPIRED';
  canEdit: boolean;
  expiresAt: string | null;
  maxUses: number | null;
  useCount: number;
  guestName: string | null;
  createdBy: { id: string; name: string | null; email: string };
  createdAt: string;
  updatedAt: string;
}

const EXPIRY_OPTIONS = [
  { value: 1, label: '1 hour' },
  { value: 24, label: '24 hours' },
  { value: 168, label: '7 days' },
  { value: 720, label: '30 days' },
  { value: 0, label: 'No expiry' },
];

function statusTag(status: string) {
  switch (status) {
    case 'ACTIVE':
      return (
        <Tag icon={<CheckCircleOutlined />} color="success">
          Active
        </Tag>
      );
    case 'REVOKED':
      return (
        <Tag icon={<CloseCircleOutlined />} color="error">
          Revoked
        </Tag>
      );
    case 'EXPIRED':
      return (
        <Tag icon={<ClockCircleOutlined />} color="default">
          Expired
        </Tag>
      );
    default:
      return <Tag>{status}</Tag>;
  }
}

export function DocSharePanel({ open, onClose, documentPath }: DocSharePanelProps) {
  const [loading, setLoading] = useState(false);
  const [creating, setCreating] = useState(false);
  const [links, setLinks] = useState<ShareLink[]>([]);
  const [generatedUrl, setGeneratedUrl] = useState<string | null>(null);

  // Form state
  const [canEdit, setCanEdit] = useState(true);
  const [expiryHours, setExpiryHours] = useState<number>(168); // 7 days default
  const [maxUses, setMaxUses] = useState<number | null>(null);
  const [guestName, setGuestName] = useState('');

  const fetchLinks = useCallback(async () => {
    if (!documentPath) return;
    setLoading(true);
    try {
      const { data } = await api.get<{ links: ShareLink[] }>('/docs-access/share/links', {
        params: { path: documentPath },
      });
      setLinks(data.links);
    } catch {
      message.error('Failed to load share links');
    } finally {
      setLoading(false);
    }
  }, [documentPath]);

  useEffect(() => {
    if (open && documentPath) {
      fetchLinks();
      setGeneratedUrl(null);
    }
  }, [open, documentPath, fetchLinks]);

  const handleCreate = async () => {
    if (!documentPath) return;
    setCreating(true);
    try {
      const payload: Record<string, unknown> = {
        documentPath,
        canEdit,
      };
      if (expiryHours > 0) {
        payload.expiresInHours = expiryHours;
      }
      if (maxUses && maxUses > 0) {
        payload.maxUses = maxUses;
      }
      if (guestName.trim()) {
        payload.guestName = guestName.trim();
      }

      const { data } = await api.post<{ id: string; shareToken: string; documentPath: string }>(
        '/docs-access/share/create',
        payload,
      );

      const url = `${window.location.origin}/docs/share/${data.shareToken}`;
      setGeneratedUrl(url);
      message.success('Share link created');
      fetchLinks();
    } catch {
      message.error('Failed to create share link');
    } finally {
      setCreating(false);
    }
  };

  const handleCopyUrl = async (url: string) => {
    try {
      await navigator.clipboard.writeText(url);
      message.success('Link copied to clipboard');
    } catch {
      message.error('Failed to copy link');
    }
  };

  const handleRevoke = async (id: string) => {
    try {
      await api.patch(`/docs-access/share/${id}/revoke`);
      message.success('Share link revoked');
      fetchLinks();
    } catch {
      message.error('Failed to revoke share link');
    }
  };

  const columns: ColumnsType<ShareLink> = [
    {
      title: 'Token',
      dataIndex: 'shareToken',
      key: 'token',
      width: 100,
      render: (token: string) => (
        <Tooltip title={token}>
          <Text code copyable={{ text: `${window.location.origin}/docs/share/${token}` }}>
            {token.substring(0, 8)}...
          </Text>
        </Tooltip>
      ),
    },
    {
      title: 'Guest',
      dataIndex: 'guestName',
      key: 'guest',
      width: 100,
      render: (name: string | null) => name || <Text type="secondary">--</Text>,
    },
    {
      title: 'Created',
      dataIndex: 'createdAt',
      key: 'created',
      width: 110,
      render: (date: string) => (
        <Tooltip title={dayjs(date).format('YYYY-MM-DD HH:mm')}>
          <span>{dayjs(date).fromNow()}</span>
        </Tooltip>
      ),
    },
    {
      title: 'Expiry',
      dataIndex: 'expiresAt',
      key: 'expiry',
      width: 110,
      render: (date: string | null) =>
        date ? (
          <Tooltip title={dayjs(date).format('YYYY-MM-DD HH:mm')}>
            <span>{dayjs(date).fromNow()}</span>
          </Tooltip>
        ) : (
          <Text type="secondary">Never</Text>
        ),
    },
    {
      title: 'Uses',
      key: 'uses',
      width: 70,
      render: (_: unknown, record: ShareLink) => (
        <span>
          {record.useCount}
          {record.maxUses ? ` / ${record.maxUses}` : ''}
        </span>
      ),
    },
    {
      title: 'Status',
      dataIndex: 'status',
      key: 'status',
      width: 90,
      render: (status: string) => statusTag(status),
    },
    {
      title: '',
      key: 'actions',
      width: 60,
      render: (_: unknown, record: ShareLink) =>
        record.status === 'ACTIVE' ? (
          <Tooltip title="Revoke">
            <Button
              type="text"
              danger
              size="small"
              icon={<StopOutlined />}
              onClick={() => handleRevoke(record.id)}
            />
          </Tooltip>
        ) : null,
    },
  ];

  const fileName = documentPath?.split('/').pop() || 'Document';

  return (
    <Drawer
      title={
        <Space>
          <ShareAltOutlined />
          <span>Share Document</span>
        </Space>
      }
      open={open}
      onClose={onClose}
      width={640}
      destroyOnClose
    >
      {!documentPath ? (
        <Alert message="No document selected" type="info" />
      ) : (
        <Space direction="vertical" style={{ width: '100%' }} size="middle">
          <div>
            <Text type="secondary">Document</Text>
            <br />
            <Text strong>{fileName}</Text>
            <br />
            <Text type="secondary" style={{ fontSize: 12 }}>
              {documentPath}
            </Text>
          </div>

          <Divider style={{ margin: '8px 0' }}>Create Share Link</Divider>

          <Form layout="vertical" style={{ width: '100%' }}>
            <Form.Item label="Can edit">
              <Switch
                checked={canEdit}
                onChange={setCanEdit}
                checkedChildren="Edit"
                unCheckedChildren="View only"
              />
            </Form.Item>

            <Form.Item label="Expiry">
              <Select
                value={expiryHours}
                onChange={setExpiryHours}
                options={EXPIRY_OPTIONS}
                style={{ width: 200 }}
              />
            </Form.Item>

            <Form.Item label="Max uses (optional)">
              <InputNumber
                min={1}
                max={1000}
                value={maxUses}
                onChange={(v) => setMaxUses(v)}
                placeholder="Unlimited"
                style={{ width: 200 }}
              />
            </Form.Item>

            <Form.Item label="Guest name (optional)">
              <Input
                value={guestName}
                onChange={(e) => setGuestName(e.target.value)}
                placeholder="Name shown to collaborators"
                maxLength={200}
                style={{ width: '100%' }}
              />
            </Form.Item>

            <Form.Item>
              <Button
                type="primary"
                icon={<LinkOutlined />}
                onClick={handleCreate}
                loading={creating}
              >
                Generate Link
              </Button>
            </Form.Item>
          </Form>

          {generatedUrl && (
            <Alert
              message="Share link created"
              description={
                <Space direction="vertical" style={{ width: '100%' }}>
                  <Paragraph
                    copyable={{
                      text: generatedUrl,
                      onCopy: () => message.success('Copied'),
                    }}
                    style={{ margin: 0, wordBreak: 'break-all' }}
                  >
                    {generatedUrl}
                  </Paragraph>
                  <Button
                    size="small"
                    icon={<CopyOutlined />}
                    onClick={() => handleCopyUrl(generatedUrl)}
                  >
                    Copy Link
                  </Button>
                </Space>
              }
              type="success"
              showIcon
              closable
              onClose={() => setGeneratedUrl(null)}
            />
          )}

          <Divider style={{ margin: '8px 0' }}>Active Links</Divider>

          <Table<ShareLink>
            columns={columns}
            dataSource={links}
            rowKey="id"
            loading={loading}
            size="small"
            pagination={false}
            scroll={{ x: 600 }}
            locale={{ emptyText: 'No share links for this document' }}
          />
        </Space>
      )}
    </Drawer>
  );
}
