import { useState, useEffect, useCallback } from 'react';
import {
  Drawer,
  Form,
  Select,
  Switch,
  Button,
  Spin,
  Tag,
  Space,
  Typography,
  Divider,
  message,
  Alert,
} from 'antd';
import {
  LockOutlined,
  TeamOutlined,
  UserOutlined,
  SaveOutlined,
  UndoOutlined,
} from '@ant-design/icons';
import { api } from '@/lib/api';

const { Text, Title } = Typography;

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

interface EffectivePolicy {
  id: string | null;
  documentPath: string;
  isDirectory: boolean;
  allowedEditors: string[];
  isDefault: boolean;
}

const AVAILABLE_ROLES: { value: string; label: string }[] = [
  { value: 'role:SUPER_ADMIN', label: 'Super Admin' },
  { value: 'role:CONTENT_ADMIN', label: 'Content Admin' },
  { value: 'role:INFLUENCE_ADMIN', label: 'Influence Admin' },
  { value: 'role:MAP_ADMIN', label: 'Map Admin' },
  { value: 'role:BROADCAST_ADMIN', label: 'Broadcast Admin' },
  { value: 'role:MEDIA_ADMIN', label: 'Media Admin' },
  { value: 'role:PAYMENTS_ADMIN', label: 'Payments Admin' },
  { value: 'role:EVENTS_ADMIN', label: 'Events Admin' },
  { value: 'role:SOCIAL_ADMIN', label: 'Social Admin' },
];

function editorLabel(editor: string): string {
  if (editor === 'all_content_editors') return 'All Content Editors';
  if (editor.startsWith('role:')) {
    const roleName = editor.substring(5);
    return roleName.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase());
  }
  if (editor.startsWith('user:')) return editor.substring(5);
  return editor;
}

function editorColor(editor: string): string {
  if (editor === 'all_content_editors') return 'green';
  if (editor.startsWith('role:')) return 'blue';
  if (editor.startsWith('user:')) return 'purple';
  return 'default';
}

export function DocAccessPolicyPanel({ open, onClose, documentPath }: DocAccessPolicyPanelProps) {
  const [loading, setLoading] = useState(false);
  const [saving, setSaving] = useState(false);
  const [policy, setPolicy] = useState<EffectivePolicy | null>(null);
  const [allContentEditors, setAllContentEditors] = useState(true);
  const [selectedRoles, setSelectedRoles] = useState<string[]>([]);
  const [userEmails, setUserEmails] = useState<string[]>([]);
  const [isDirectory, setIsDirectory] = useState(false);

  const fetchPolicy = useCallback(async () => {
    if (!documentPath) return;
    setLoading(true);
    try {
      const { data } = await api.get<EffectivePolicy>('/docs-access/policy', {
        params: { path: documentPath },
      });
      setPolicy(data);

      // Parse allowedEditors into form state
      const hasAllContentEditors = data.allowedEditors.includes('all_content_editors');
      setAllContentEditors(hasAllContentEditors);
      setIsDirectory(data.isDirectory);

      const roles: string[] = [];
      const users: string[] = [];
      for (const editor of data.allowedEditors) {
        if (editor === 'all_content_editors') continue;
        if (editor.startsWith('role:')) roles.push(editor);
        else if (editor.startsWith('user:')) users.push(editor.substring(5));
      }
      setSelectedRoles(roles);
      setUserEmails(users);
    } catch {
      message.error('Failed to load access policy');
    } finally {
      setLoading(false);
    }
  }, [documentPath]);

  useEffect(() => {
    if (open && documentPath) {
      fetchPolicy();
    }
  }, [open, documentPath, fetchPolicy]);

  const handleSave = async () => {
    if (!documentPath) return;
    setSaving(true);
    try {
      const allowedEditors: string[] = [];
      if (allContentEditors) {
        allowedEditors.push('all_content_editors');
      }
      allowedEditors.push(...selectedRoles);
      allowedEditors.push(...userEmails.map((e) => `user:${e}`));

      if (allowedEditors.length === 0) {
        message.warning('At least one editor must be specified');
        setSaving(false);
        return;
      }

      await api.put('/docs-access/policy', {
        documentPath,
        isDirectory,
        allowedEditors,
      });

      message.success('Access policy saved');
      fetchPolicy();
    } catch {
      message.error('Failed to save access policy');
    } finally {
      setSaving(false);
    }
  };

  const handleReset = async () => {
    if (!documentPath) return;
    setSaving(true);
    try {
      await api.delete('/docs-access/policy', {
        params: { path: documentPath },
      });
      message.success('Policy reset to default');
      fetchPolicy();
    } catch {
      message.error('Failed to reset policy');
    } finally {
      setSaving(false);
    }
  };

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

  return (
    <Drawer
      title={
        <Space>
          <LockOutlined />
          <span>Access Policy</span>
        </Space>
      }
      open={open}
      onClose={onClose}
      width={480}
      destroyOnClose
    >
      {loading ? (
        <div style={{ textAlign: 'center', padding: 40 }}>
          <Spin size="large" />
        </div>
      ) : !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>

            {policy?.isDefault && !policy.id && (
              <Alert
                message="Default policy"
                description="No custom policy is set. All content editors can edit this file."
                type="info"
                showIcon
              />
            )}

            {policy && !policy.isDefault && (
              <Alert
                message="Custom policy active"
                description={
                  policy.isDirectory
                    ? `Directory policy applied from: ${policy.documentPath}`
                    : 'File-specific policy'
                }
                type="warning"
                showIcon
              />
            )}

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

            <Title level={5} style={{ margin: 0 }}>
              Current Editors
            </Title>
            <div>
              {policy?.allowedEditors.map((editor) => (
                <Tag
                  key={editor}
                  color={editorColor(editor)}
                  icon={
                    editor === 'all_content_editors' ? (
                      <TeamOutlined />
                    ) : editor.startsWith('user:') ? (
                      <UserOutlined />
                    ) : undefined
                  }
                  style={{ marginBottom: 4 }}
                >
                  {editorLabel(editor)}
                </Tag>
              ))}
            </div>

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

            <Title level={5} style={{ margin: 0 }}>
              Edit Policy
            </Title>

            <Form layout="vertical" style={{ width: '100%' }}>
              <Form.Item label="All content editors (default)">
                <Switch
                  checked={allContentEditors}
                  onChange={setAllContentEditors}
                  checkedChildren="On"
                  unCheckedChildren="Off"
                />
              </Form.Item>

              <Form.Item label="Additional roles">
                <Select
                  mode="multiple"
                  value={selectedRoles}
                  onChange={setSelectedRoles}
                  options={AVAILABLE_ROLES}
                  placeholder="Select roles..."
                  allowClear
                  style={{ width: '100%' }}
                />
              </Form.Item>

              <Form.Item label="Specific users (by email)">
                <Select
                  mode="tags"
                  value={userEmails}
                  onChange={setUserEmails}
                  placeholder="Type email and press Enter..."
                  tokenSeparators={[',']}
                  style={{ width: '100%' }}
                />
              </Form.Item>

              <Form.Item label="Apply to directory">
                <Switch
                  checked={isDirectory}
                  onChange={setIsDirectory}
                  checkedChildren="Directory"
                  unCheckedChildren="File only"
                />
                {isDirectory && (
                  <Text type="secondary" style={{ display: 'block', marginTop: 4, fontSize: 12 }}>
                    This policy will apply to all files within this directory and subdirectories.
                  </Text>
                )}
              </Form.Item>

              <Form.Item>
                <Space>
                  <Button
                    type="primary"
                    icon={<SaveOutlined />}
                    onClick={handleSave}
                    loading={saving}
                  >
                    Save Policy
                  </Button>
                  <Button
                    icon={<UndoOutlined />}
                    onClick={handleReset}
                    loading={saving}
                    disabled={policy?.isDefault ?? true}
                  >
                    Reset to Default
                  </Button>
                </Space>
              </Form.Item>
            </Form>
          </Space>
        </>
      )}
    </Drawer>
  );
}
