import React, { useState, useEffect } from 'react';
import {
  Table,
  Button,
  Space,
  Typography,
  Modal,
  Form,
  Input,
  Select,
  message,
  Popconfirm,
  Tag,
  Card,
  Row,
  Col,
  Alert,
  Checkbox,
} from 'antd';
import {
  PlusOutlined,
  DeleteOutlined,
  EyeOutlined,
  CopyOutlined,
  CheckCircleOutlined,
  ExclamationCircleOutlined,
} from '@ant-design/icons';
import { apiService, Application, StaticToken, CreateTokenRequest, CreateTokenResponse, VerifyRequest } from '../services/apiService';
import dayjs from 'dayjs';

const { Title, Text } = Typography;
const { Option } = Select;
const { TextArea } = Input;

interface TokenWithApp extends StaticToken {
  app?: Application;
}

const availablePermissions = [
  'app.read',
  'app.write',
  'app.delete',
  'token.read',
  'token.create',
  'token.revoke',
  'repo.read',
  'repo.write',
  'repo.admin',
  'permission.read',
  'permission.write',
  'permission.grant',
  'permission.revoke',
];

const Tokens: React.FC = () => {
  const [tokens, setTokens] = useState<TokenWithApp[]>([]);
  const [applications, setApplications] = useState<Application[]>([]);
  const [loading, setLoading] = useState(false);
  const [modalVisible, setModalVisible] = useState(false);
  const [verifyModalVisible, setVerifyModalVisible] = useState(false);
  const [tokenDetailsVisible, setTokenDetailsVisible] = useState(false);
  const [selectedToken, setSelectedToken] = useState<TokenWithApp | null>(null);
  const [newTokenResponse, setNewTokenResponse] = useState<CreateTokenResponse | null>(null);
  const [form] = Form.useForm();
  const [verifyForm] = Form.useForm();

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

  const loadApplications = async () => {
    try {
      setLoading(true);
      const response = await apiService.getApplications();
      setApplications(response.data);
      if (response.data.length > 0) {
        loadAllTokens(response.data);
      }
    } catch (error) {
      console.error('Failed to load applications:', error);
      message.error('Failed to load applications');
    } finally {
      setLoading(false);
    }
  };

  const loadAllTokens = async (apps: Application[]) => {
    try {
      const allTokens: TokenWithApp[] = [];
      
      for (const app of apps) {
        try {
          const tokensResponse = await apiService.getTokensForApplication(app.app_id);
          const tokensWithApp = tokensResponse.data.map(token => ({
            ...token,
            app,
          }));
          allTokens.push(...tokensWithApp);
        } catch (error) {
          console.warn(`Failed to load tokens for app ${app.app_id}:`, error);
        }
      }
      
      setTokens(allTokens);
    } catch (error) {
      console.error('Failed to load tokens:', error);
      message.error('Failed to load tokens');
    }
  };

  const handleCreate = () => {
    form.resetFields();
    setNewTokenResponse(null);
    setModalVisible(true);
  };

  const handleDelete = async (tokenId: string) => {
    try {
      await apiService.deleteToken(tokenId);
      message.success('Token deleted successfully');
      loadApplications();
    } catch (error) {
      console.error('Failed to delete token:', error);
      message.error('Failed to delete token');
    }
  };

  const handleSubmit = async (values: any) => {
    try {
      // Debug logging to identify the issue
      console.log('Form values:', values);
      console.log('App ID:', values.app_id);
      
      // More robust validation for app_id
      if (!values.app_id || values.app_id === 'undefined' || values.app_id === undefined) {
        console.error('Invalid app_id detected:', values.app_id);
        message.error('Please select an application');
        return;
      }

      // Validate that the app_id exists in our applications list
      const selectedApp = applications.find(app => app.app_id === values.app_id);
      if (!selectedApp) {
        console.error('Selected app_id not found in applications list:', values.app_id);
        message.error('Selected application is not valid. Please refresh and try again.');
        return;
      }

      const requestData: CreateTokenRequest = {
        owner: {
          type: values.owner_type,
          name: values.owner_name,
          owner: values.owner_owner,
        },
        permissions: values.permissions,
      };

      console.log('Creating token for app:', values.app_id);
      console.log('Request data:', requestData);

      const response = await apiService.createToken(values.app_id, requestData);
      console.log('Token creation response:', response);
      setNewTokenResponse(response);
      message.success('Token created successfully');
      loadApplications();
    } catch (error) {
      console.error('Failed to create token:', error);
      message.error('Failed to create token');
    }
  };

  const handleVerifyToken = async (values: any) => {
    try {
      const verifyRequest: VerifyRequest = {
        app_id: values.app_id,
        type: 'static',
        token: values.token,
        permissions: values.permissions || [],
      };

      const response = await apiService.verifyToken(verifyRequest);
      
      Modal.info({
        title: 'Token Verification Result',
        width: 600,
        content: (
          <div>
            <Space direction="vertical" size="middle" style={{ width: '100%' }}>
              <div>
                <Text strong>Status: </Text>
                {response.valid ? (
                  <Tag color="green" icon={<CheckCircleOutlined />}>VALID</Tag>
                ) : (
                  <Tag color="red" icon={<ExclamationCircleOutlined />}>INVALID</Tag>
                )}
              </div>
              
              {response.permissions && response.permissions.length > 0 && (
                <div>
                  <Text strong>Permissions:</Text>
                  <div style={{ marginTop: '8px' }}>
                    {response.permissions.map(permission => (
                      <Tag key={permission} color="blue">{permission}</Tag>
                    ))}
                  </div>
                </div>
              )}
              
              {response.permission_results && (
                <div>
                  <Text strong>Permission Check Results:</Text>
                  <div style={{ marginTop: '8px' }}>
                    {Object.entries(response.permission_results).map(([permission, granted]) => (
                      <div key={permission} style={{ marginBottom: '4px' }}>
                        <Tag color={granted ? 'green' : 'red'}>
                          {permission}: {granted ? 'GRANTED' : 'DENIED'}
                        </Tag>
                      </div>
                    ))}
                  </div>
                </div>
              )}
              
              {response.error && (
                <Alert
                  message="Error"
                  description={response.error}
                  type="error"
                  showIcon
                />
              )}
            </Space>
          </div>
        ),
      });
    } catch (error) {
      console.error('Failed to verify token:', error);
      message.error('Failed to verify token');
    }
  };

  const showTokenDetails = (token: TokenWithApp) => {
    setSelectedToken(token);
    setTokenDetailsVisible(true);
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    message.success('Copied to clipboard');
  };

  const columns = [
    {
      title: 'Token ID',
      dataIndex: 'id',
      key: 'id',
      render: (text: string) => <Text code>{text.substring(0, 8)}...</Text>,
    },
    {
      title: 'Application',
      dataIndex: 'app',
      key: 'app',
      render: (app: Application) => (
        <div>
          <Text strong>{app?.app_id || 'Unknown'}</Text>
          <br />
          <Text type="secondary" style={{ fontSize: '12px' }}>
            {app?.app_link || ''}
          </Text>
        </div>
      ),
    },
    {
      title: 'Owner',
      dataIndex: 'owner',
      key: 'owner',
      render: (owner: StaticToken['owner']) => (
        <div>
          <div>{owner.name}</div>
          <Text type="secondary" style={{ fontSize: '12px' }}>
            {owner.type} • {owner.owner}
          </Text>
        </div>
      ),
    },
    {
      title: 'Type',
      dataIndex: 'type',
      key: 'type',
      render: (type: string) => (
        <Tag color="blue">{type.toUpperCase()}</Tag>
      ),
    },
    {
      title: 'Created',
      dataIndex: 'created_at',
      key: 'created_at',
      render: (date: string) => dayjs(date).format('MMM DD, YYYY'),
    },
    {
      title: 'Actions',
      key: 'actions',
      render: (_: any, record: TokenWithApp) => (
        <Space>
          <Button
            type="text"
            icon={<EyeOutlined />}
            onClick={() => showTokenDetails(record)}
            title="View Details"
          />
          <Popconfirm
            title="Are you sure you want to delete this token?"
            onConfirm={() => handleDelete(record.id)}
            okText="Yes"
            cancelText="No"
          >
            <Button
              type="text"
              danger
              icon={<DeleteOutlined />}
              title="Delete"
            />
          </Popconfirm>
        </Space>
      ),
    },
  ];

  return (
    <div>
      <Space direction="vertical" size="large" style={{ width: '100%' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <Title level={2}>Tokens</Title>
            <Text type="secondary">
              Manage static tokens for your applications
            </Text>
          </div>
          <Space>
            <Button
              icon={<CheckCircleOutlined />}
              onClick={() => setVerifyModalVisible(true)}
            >
              Verify Token
            </Button>
            <Button
              type="primary"
              icon={<PlusOutlined />}
              onClick={handleCreate}
            >
              Create Token
            </Button>
          </Space>
        </div>

        <Table
          columns={columns}
          dataSource={tokens}
          rowKey="id"
          loading={loading}
          pagination={{
            pageSize: 10,
            showSizeChanger: true,
            showQuickJumper: true,
            showTotal: (total, range) =>
              `${range[0]}-${range[1]} of ${total} tokens`,
          }}
        />
      </Space>

      {/* Create Token Modal */}
      <Modal
        title="Create Static Token"
        open={modalVisible}
        onCancel={() => setModalVisible(false)}
        onOk={() => form.submit()}
        width={600}
      >
        {newTokenResponse ? (
          <Space direction="vertical" size="large" style={{ width: '100%' }}>
            <Alert
              message="Token Created Successfully"
              description="Please copy and save this token securely. It will not be shown again."
              type="success"
              showIcon
            />
            
            <Card title="New Token Details">
              <Space direction="vertical" size="middle" style={{ width: '100%' }}>
                <div>
                  <Text strong>Token ID:</Text>
                  <div>
                    <Text code>{newTokenResponse.id}</Text>
                    <Button
                      type="text"
                      size="small"
                      icon={<CopyOutlined />}
                      onClick={() => copyToClipboard(newTokenResponse.id)}
                    />
                  </div>
                </div>
                
                <div>
                  <Text strong>Token:</Text>
                  <div>
                    <TextArea
                      value={newTokenResponse.token}
                      readOnly
                      rows={3}
                      style={{ fontFamily: 'monospace' }}
                    />
                    <Button
                      type="text"
                      size="small"
                      icon={<CopyOutlined />}
                      onClick={() => copyToClipboard(newTokenResponse.token)}
                      style={{ marginTop: '8px' }}
                    >
                      Copy Token
                    </Button>
                  </div>
                </div>
                
                <div>
                  <Text strong>Permissions:</Text>
                  <div style={{ marginTop: '8px' }}>
                    {newTokenResponse.permissions.map(permission => (
                      <Tag key={permission} color="blue">{permission}</Tag>
                    ))}
                  </div>
                </div>
                
                <div>
                  <Text strong>Created:</Text>
                  <div>{dayjs(newTokenResponse.created_at).format('MMMM DD, YYYY HH:mm:ss')}</div>
                </div>
              </Space>
            </Card>
          </Space>
        ) : (
          <Form
            form={form}
            layout="vertical"
            onFinish={handleSubmit}
          >
            <Form.Item
              name="app_id"
              label="Application"
              rules={[{ required: true, message: 'Please select an application' }]}
            >
              <Select placeholder="Select application">
                {applications.map(app => (
                  <Option key={app.app_id} value={app.app_id}>
                    {app.app_id}
                  </Option>
                ))}
              </Select>
            </Form.Item>

            <Form.Item
              name="permissions"
              label="Permissions"
              rules={[{ required: true, message: 'Please select at least one permission' }]}
            >
              <Checkbox.Group>
                <Row>
                  {availablePermissions.map(permission => (
                    <Col span={8} key={permission} style={{ marginBottom: '8px' }}>
                      <Checkbox value={permission}>{permission}</Checkbox>
                    </Col>
                  ))}
                </Row>
              </Checkbox.Group>
            </Form.Item>

            <Form.Item
              name="owner_type"
              label="Owner Type"
              rules={[{ required: true, message: 'Please select owner type' }]}
            >
              <Select placeholder="Select owner type">
                <Option value="individual">Individual</Option>
                <Option value="team">Team</Option>
              </Select>
            </Form.Item>

            <Row gutter={16}>
              <Col span={12}>
                <Form.Item
                  name="owner_name"
                  label="Owner Name"
                  rules={[{ required: true, message: 'Please enter owner name' }]}
                >
                  <Input placeholder="John Doe" />
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item
                  name="owner_owner"
                  label="Owner Contact"
                  rules={[{ required: true, message: 'Please enter owner contact' }]}
                >
                  <Input placeholder="john.doe@example.com" />
                </Form.Item>
              </Col>
            </Row>
          </Form>
        )}
      </Modal>

      {/* Verify Token Modal */}
      <Modal
        title="Verify Token"
        open={verifyModalVisible}
        onCancel={() => setVerifyModalVisible(false)}
        onOk={() => verifyForm.submit()}
        width={600}
      >
        <Form
          form={verifyForm}
          layout="vertical"
          onFinish={handleVerifyToken}
        >
          <Form.Item
            name="app_id"
            label="Application"
            rules={[{ required: true, message: 'Please select an application' }]}
          >
            <Select placeholder="Select application">
              {applications.map(app => (
                <Option key={app.app_id} value={app.app_id}>
                  {app.app_id}
                </Option>
              ))}
            </Select>
          </Form.Item>

          <Form.Item
            name="token"
            label="Token"
            rules={[{ required: true, message: 'Please enter the token to verify' }]}
          >
            <TextArea
              placeholder="Enter the token to verify"
              rows={3}
              style={{ fontFamily: 'monospace' }}
            />
          </Form.Item>

          <Form.Item
            name="permissions"
            label="Permissions to Check (Optional)"
          >
            <Checkbox.Group>
              <Row>
                {availablePermissions.map(permission => (
                  <Col span={8} key={permission} style={{ marginBottom: '8px' }}>
                    <Checkbox value={permission}>{permission}</Checkbox>
                  </Col>
                ))}
              </Row>
            </Checkbox.Group>
          </Form.Item>
        </Form>
      </Modal>

      {/* Token Details Modal */}
      <Modal
        title="Token Details"
        open={tokenDetailsVisible}
        onCancel={() => setTokenDetailsVisible(false)}
        footer={[
          <Button key="close" onClick={() => setTokenDetailsVisible(false)}>
            Close
          </Button>,
        ]}
        width={600}
      >
        {selectedToken && (
          <Space direction="vertical" size="middle" style={{ width: '100%' }}>
            <Card title="Token Information">
              <Row gutter={16}>
                <Col span={12}>
                  <Text strong>Token ID:</Text>
                  <div>
                    <Text code>{selectedToken.id}</Text>
                    <Button
                      type="text"
                      size="small"
                      icon={<CopyOutlined />}
                      onClick={() => copyToClipboard(selectedToken.id)}
                    />
                  </div>
                </Col>
                <Col span={12}>
                  <Text strong>Type:</Text>
                  <div>
                    <Tag color="blue">{selectedToken.type.toUpperCase()}</Tag>
                  </div>
                </Col>
              </Row>
            </Card>

            <Card title="Application">
              <Row gutter={16}>
                <Col span={12}>
                  <Text strong>App ID:</Text>
                  <div>
                    <Text code>{selectedToken.app?.app_id}</Text>
                  </div>
                </Col>
                <Col span={12}>
                  <Text strong>App Link:</Text>
                  <div>
                    <a href={selectedToken.app?.app_link} target="_blank" rel="noopener noreferrer">
                      {selectedToken.app?.app_link}
                    </a>
                  </div>
                </Col>
              </Row>
            </Card>

            <Card title="Owner Information">
              <Row gutter={16}>
                <Col span={8}>
                  <Text strong>Type:</Text>
                  <div>
                    <Tag color={selectedToken.owner.type === 'individual' ? 'blue' : 'green'}>
                      {selectedToken.owner.type.toUpperCase()}
                    </Tag>
                  </div>
                </Col>
                <Col span={8}>
                  <Text strong>Name:</Text>
                  <div>{selectedToken.owner.name}</div>
                </Col>
                <Col span={8}>
                  <Text strong>Contact:</Text>
                  <div>{selectedToken.owner.owner}</div>
                </Col>
              </Row>
            </Card>

            <Card title="Timestamps">
              <Row gutter={16}>
                <Col span={12}>
                  <Text strong>Created:</Text>
                  <div>{dayjs(selectedToken.created_at).format('MMMM DD, YYYY HH:mm:ss')}</div>
                </Col>
                <Col span={12}>
                  <Text strong>Updated:</Text>
                  <div>{dayjs(selectedToken.updated_at).format('MMMM DD, YYYY HH:mm:ss')}</div>
                </Col>
              </Row>
            </Card>
          </Space>
        )}
      </Modal>
    </div>
  );
};

export default Tokens;
