import React, { useState, useEffect } from 'react';
import {
  Card,
  Button,
  Form,
  Input,
  Select,
  Space,
  Typography,
  Alert,
  Divider,
  Row,
  Col,
  Tag,
  Checkbox,
  message,
  Modal,
  Steps,
} from 'antd';
import {
  PlayCircleOutlined,
  CheckCircleOutlined,
  ExclamationCircleOutlined,
  CopyOutlined,
  ReloadOutlined,
  LinkOutlined,
} from '@ant-design/icons';
import { apiService, Application } from '../services/apiService';

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

interface LoginTestResult {
  success: boolean;
  token?: string;
  redirectUrl?: string;
  userId?: string;
  appId?: string;
  expiresIn?: number;
  error?: string;
  timestamp: string;
}

interface CallbackTestResult {
  success: boolean;
  token?: string;
  verified?: boolean;
  permitted?: boolean;
  user_id?: string;
  permissions?: string[];
  permission_results?: Record<string, boolean>;
  expires_at?: string;
  max_valid_at?: string;
  token_type?: string;
  error?: string;
  timestamp: string;
}

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 TokenTester: React.FC = () => {
  const [applications, setApplications] = useState<Application[]>([]);
  const [loading, setLoading] = useState(false);
  const [testLoading, setTestLoading] = useState(false);
  const [callbackLoading, setCallbackLoading] = useState(false);
  const [loginResult, setLoginResult] = useState<LoginTestResult | null>(null);
  const [callbackResult, setCallbackResult] = useState<CallbackTestResult | null>(null);
  const [currentStep, setCurrentStep] = useState(0);
  const [callbackModalVisible, setCallbackModalVisible] = useState(false);
  const [form] = Form.useForm();
  const [callbackForm] = Form.useForm();
  const [useCallback, setUseCallback] = useState(false);
  const [extractedToken, setExtractedToken] = useState('');

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

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

  const handleLoginTest = async (values: any) => {
    try {
      setTestLoading(true);
      setCurrentStep(1);
      
      const selectedApp = applications.find(app => app.app_id === values.app_id);
      const callbackUrl = `${window.location.origin}/token-tester/callback`;
      
      // Store test data in localStorage for the callback page
      const testData = {
        app_id: values.app_id,
        permissions: values.permissions || [],
        use_callback: values.use_callback,
        timestamp: new Date().toISOString(),
      };
      localStorage.setItem('token_tester_data', JSON.stringify(testData));
      
      console.log('Testing login flow with:', {
        app_id: values.app_id,
        permissions: values.permissions || [],
        redirect_uri: values.use_callback ? callbackUrl : undefined,
      });

      const response = await apiService.login(
        values.app_id,
        values.permissions || [],
        values.use_callback ? callbackUrl : undefined,
        values.token_delivery || 'query'
      );

      console.log('Login response:', response);

      const result: LoginTestResult = {
        success: true,
        token: response.token,
        redirectUrl: response.redirect_url,
        userId: response.user_id,
        appId: values.app_id,
        expiresIn: response.expires_in,
        timestamp: new Date().toISOString(),
      };

      setLoginResult(result);
      setCurrentStep(2);
      
      message.success('Login test completed successfully!');

      // If we have a redirect URL, show the callback modal
      if (response.redirect_url && values.use_callback) {
        setCallbackModalVisible(true);
        
        // Extract token from redirect URL if using query parameter delivery
        let tokenFromUrl = '';
        if (values.token_delivery === 'query') {
          try {
            const url = new URL(response.redirect_url);
            tokenFromUrl = url.searchParams.get('token') || '';
          } catch (e) {
            console.warn('Failed to parse redirect URL for token extraction:', e);
          }
        }
        
        setExtractedToken(tokenFromUrl);
        
        callbackForm.setFieldsValue({
          app_id: values.app_id,
          token: tokenFromUrl, // Pre-fill with extracted token if available
          permissions: values.permissions || [],
        });
      }

    } catch (error: any) {
      console.error('Login test failed:', error);
      
      const result: LoginTestResult = {
        success: false,
        error: error.response?.data?.message || error.message || 'Login test failed',
        timestamp: new Date().toISOString(),
      };
      
      setLoginResult(result);
      setCurrentStep(2);
      message.error('Login test failed');
    } finally {
      setTestLoading(false);
    }
  };

  const handleCallbackTest = async (values: any) => {
    try {
      setCallbackLoading(true);
      setCurrentStep(3);

      console.log('Testing callback with token verification:', values);

      // Verify the token received in the callback (type will be auto-detected)
      const verifyResponse = await apiService.verifyToken({
        app_id: values.app_id,
        token: values.token,
        permissions: values.permissions || [],
      });

      console.log('Token verification response:', verifyResponse);

      const result: CallbackTestResult = {
        success: verifyResponse.valid,
        token: values.token,
        verified: verifyResponse.valid,
        permitted: verifyResponse.permitted,
        user_id: verifyResponse.user_id,
        permissions: verifyResponse.permissions,
        permission_results: verifyResponse.permission_results,
        expires_at: verifyResponse.expires_at,
        max_valid_at: verifyResponse.max_valid_at,
        token_type: verifyResponse.token_type,
        error: verifyResponse.error,
        timestamp: new Date().toISOString(),
      };

      setCallbackResult(result);
      setCurrentStep(4);
      
      if (verifyResponse.valid) {
        message.success('Callback test completed successfully!');
        // Auto-close modal after successful verification to show results
        setTimeout(() => {
          setCallbackModalVisible(false);
        }, 1500);
      } else {
        message.warning('Callback test completed - token verification failed');
        // Auto-close modal after failed verification to show results
        setTimeout(() => {
          setCallbackModalVisible(false);
        }, 1500);
      }

    } catch (error: any) {
      console.error('Callback test failed:', error);
      
      const result: CallbackTestResult = {
        success: false,
        error: error.response?.data?.message || error.message || 'Callback test failed',
        timestamp: new Date().toISOString(),
      };
      
      setCallbackResult(result);
      setCurrentStep(4);
      message.error('Callback test failed');
      
      // Auto-close modal to show error results
      setTimeout(() => {
        setCallbackModalVisible(false);
      }, 1500);
    } finally {
      setCallbackLoading(false);
    }
  };

  const resetTest = () => {
    setCurrentStep(0);
    setLoginResult(null);
    setCallbackResult(null);
    setCallbackModalVisible(false);
    setUseCallback(false);
    setExtractedToken('');
    form.resetFields();
    callbackForm.resetFields();
    // Clear stored test data
    localStorage.removeItem('token_tester_data');
  };

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

  const openCallbackUrl = () => {
    if (loginResult?.redirectUrl) {
      window.open(loginResult.redirectUrl, '_blank');
    }
  };

  return (
    <div>
      <Space direction="vertical" size="large" style={{ width: '100%' }}>
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <Title level={2}>Token Tester</Title>
            <Text type="secondary">
              Test the /login flow and callback handling for user tokens
            </Text>
            <div style={{ marginTop: '8px' }}>
              <Alert
                message="Two Testing Modes Available"
                description={
                  <div>
                    <Text strong>Direct Mode:</Text> Login returns token directly in response body (no callback)<br/>
                    <Text strong>Callback Mode:</Text> Login returns redirect URL, token in query parameter (default) or secure cookie
                  </div>
                }
                type="info"
                showIcon
                style={{ fontSize: '12px' }}
              />
            </div>
          </div>
          <Button
            icon={<ReloadOutlined />}
            onClick={resetTest}
            disabled={testLoading || callbackLoading}
          >
            Reset Test
          </Button>
        </div>

        {/* Test Progress */}
        <Card title="Test Progress">
          <Steps current={currentStep} size="small">
            <Step title="Configure" description="Set up test parameters" />
            <Step title="Login Test" description="Test /login endpoint" />
            <Step title="Results" description="Review login results" />
            <Step title="Callback Test" description="Test callback handling" />
            <Step title="Complete" description="Test completed" />
          </Steps>
        </Card>

        {/* Test Configuration */}
        <Card title="Test Configuration">
          <Form
            form={form}
            layout="vertical"
            onFinish={handleLoginTest}
          >
            <Row gutter={16}>
              <Col span={12}>
                <Form.Item
                  name="app_id"
                  label="Application"
                  rules={[{ required: true, message: 'Please select an application' }]}
                >
                  <Select 
                    placeholder="Select application to test"
                    loading={loading}
                  >
                    {applications.map(app => (
                      <Option key={app.app_id} value={app.app_id}>
                        <div>
                          <Text strong>{app.app_id}</Text>
                          <br />
                          <Text type="secondary" style={{ fontSize: '12px' }}>
                            {app.app_link}
                          </Text>
                        </div>
                      </Option>
                    ))}
                  </Select>
                </Form.Item>
              </Col>
              <Col span={12}>
                <Form.Item
                  name="use_callback"
                  valuePropName="checked"
                  label=" "
                >
                  <Checkbox onChange={(e) => setUseCallback(e.target.checked)}>
                    Use callback URL (test full flow)
                  </Checkbox>
                </Form.Item>
              </Col>
            </Row>

            <Form.Item
              name="token_delivery"
              label="Token Delivery Method (for callback flows)"
              tooltip="Choose how tokens are delivered when using callback URLs"
              initialValue="query"
            >
              <Select placeholder="Select delivery method" disabled={!useCallback} defaultValue="query">
                <Option value="query">
                  <div>
                    <Text strong>Query Parameter</Text> (Recommended for testing)
                    <br />
                    <Text type="secondary" style={{ fontSize: '12px' }}>
                      Token included in callback URL query string
                    </Text>
                  </div>
                </Option>
                <Option value="cookie">
                  <div>
                    <Text strong>Cookie</Text> (More secure for production)
                    <br />
                    <Text type="secondary" style={{ fontSize: '12px' }}>
                      Token stored in HTTP-only cookie
                    </Text>
                  </div>
                </Option>
              </Select>
            </Form.Item>

            <Row gutter={16}>
            </Row>

            <Form.Item
              name="permissions"
              label="Permissions to Request"
            >
              <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>
              <Button
                type="primary"
                htmlType="submit"
                icon={<PlayCircleOutlined />}
                loading={testLoading}
                size="large"
              >
                Start Login Test
              </Button>
            </Form.Item>
          </Form>
        </Card>

        {/* Login Test Results */}
        {loginResult && (
          <Card 
            title={
              <Space>
                {loginResult.success ? (
                  <CheckCircleOutlined style={{ color: '#52c41a' }} />
                ) : (
                  <ExclamationCircleOutlined style={{ color: '#ff4d4f' }} />
                )}
                Login Test Results
              </Space>
            }
          >
            <Space direction="vertical" size="middle" style={{ width: '100%' }}>
              <Alert
                message={loginResult.success ? 'Login Test Successful' : 'Login Test Failed'}
                description={loginResult.success 
                  ? 'The /login endpoint responded successfully'
                  : loginResult.error
                }
                type={loginResult.success ? 'success' : 'error'}
                showIcon
              />

              {loginResult.success && (
                <div>
                  <Row gutter={16}>
                    {loginResult.token && (
                      <Col span={12}>
                        <Card size="small" title="User Token">
                          <Space direction="vertical" style={{ width: '100%' }}>
                            <TextArea
                              value={loginResult.token}
                              readOnly
                              rows={3}
                              style={{ fontFamily: 'monospace', fontSize: '12px' }}
                            />
                            <Button
                              size="small"
                              icon={<CopyOutlined />}
                              onClick={() => copyToClipboard(loginResult.token!)}
                            >
                              Copy Token
                            </Button>
                          </Space>
                        </Card>
                      </Col>
                    )}
                    
                    {loginResult.redirectUrl && (
                      <Col span={12}>
                        <Card size="small" title="Redirect URL">
                          <Space direction="vertical" style={{ width: '100%' }}>
                            <Text code style={{ fontSize: '12px', wordBreak: 'break-all' }}>
                              {loginResult.redirectUrl}
                            </Text>
                            <Space>
                              <Button
                                size="small"
                                icon={<CopyOutlined />}
                                onClick={() => copyToClipboard(loginResult.redirectUrl!)}
                              >
                                Copy URL
                              </Button>
                              <Button
                                size="small"
                                icon={<LinkOutlined />}
                                onClick={openCallbackUrl}
                              >
                                Open URL
                              </Button>
                            </Space>
                          </Space>
                        </Card>
                      </Col>
                    )}
                  </Row>

                  <Divider />

                  <Row gutter={16}>
                    <Col span={6}>
                      <Text strong>User ID:</Text>
                      <div>{loginResult.userId || 'N/A'}</div>
                    </Col>
                    <Col span={6}>
                      <Text strong>App ID:</Text>
                      <div>{loginResult.appId}</div>
                    </Col>
                    <Col span={6}>
                      <Text strong>Expires In:</Text>
                      <div>{loginResult.expiresIn ? `${loginResult.expiresIn}s` : 'N/A'}</div>
                    </Col>
                    <Col span={6}>
                      <Text strong>Timestamp:</Text>
                      <div>{new Date(loginResult.timestamp).toLocaleString()}</div>
                    </Col>
                  </Row>
                </div>
              )}
            </Space>
          </Card>
        )}

        {/* Callback Test Results */}
        {callbackResult && (
          <Card 
            title={
              <Space>
                {callbackResult.success ? (
                  <CheckCircleOutlined style={{ color: '#52c41a' }} />
                ) : (
                  <ExclamationCircleOutlined style={{ color: '#ff4d4f' }} />
                )}
                Callback Test Results
              </Space>
            }
          >
            <Space direction="vertical" size="middle" style={{ width: '100%' }}>
              <Alert
                message={callbackResult.success ? 'Callback Test Successful' : 'Callback Test Failed'}
                description={callbackResult.success 
                  ? 'Token verification in callback was successful'
                  : callbackResult.error
                }
                type={callbackResult.success ? 'success' : 'error'}
                showIcon
              />

              {callbackResult.success && (
                <div>
                  <Row gutter={16}>
                    <Col span={12}>
                      <Card size="small" title="Token Information">
                        <Space direction="vertical" style={{ width: '100%' }}>
                          <div>
                            <Text strong>Token Type:</Text>
                            <div>
                              <Tag color="blue">{(callbackResult.token_type || 'user').toUpperCase()}</Tag>
                            </div>
                          </div>
                          
                          {callbackResult.user_id && (
                            <div>
                              <Text strong>User ID:</Text>
                              <div>{callbackResult.user_id}</div>
                            </div>
                          )}

                          {callbackResult.expires_at && (
                            <div>
                              <Text strong>Expires At:</Text>
                              <div>{new Date(callbackResult.expires_at).toLocaleString()}</div>
                            </div>
                          )}

                          {callbackResult.max_valid_at && (
                            <div>
                              <Text strong>Max Valid Until:</Text>
                              <div>{new Date(callbackResult.max_valid_at).toLocaleString()}</div>
                            </div>
                          )}
                        </Space>
                      </Card>
                    </Col>

                    <Col span={12}>
                      <Card size="small" title="Permissions">
                        <Space direction="vertical" style={{ width: '100%' }}>
                          {callbackResult.permissions && callbackResult.permissions.length > 0 ? (
                            <div>
                              <Text strong>Available Permissions:</Text>
                              <div style={{ marginTop: '8px' }}>
                                {callbackResult.permissions.map(permission => (
                                  <Tag key={permission} color="green" style={{ margin: '2px' }}>
                                    {permission}
                                  </Tag>
                                ))}
                              </div>
                            </div>
                          ) : (
                            <Text type="secondary">No permissions available</Text>
                          )}

                          {callbackResult.permission_results && Object.keys(callbackResult.permission_results).length > 0 && (
                            <div style={{ marginTop: '16px' }}>
                              <Text strong>Permission Check Results:</Text>
                              <div style={{ marginTop: '8px' }}>
                                {Object.entries(callbackResult.permission_results).map(([permission, granted]) => (
                                  <div key={permission} style={{ marginBottom: '4px' }}>
                                    <Tag color={granted ? 'green' : 'red'}>
                                      {permission}: {granted ? 'GRANTED' : 'DENIED'}
                                    </Tag>
                                  </div>
                                ))}
                              </div>
                            </div>
                          )}
                        </Space>
                      </Card>
                    </Col>
                  </Row>
                </div>
              )}

              <div style={{ marginTop: '16px' }}>
                <Text strong>Timestamp:</Text>
                <div>{new Date(callbackResult.timestamp).toLocaleString()}</div>
              </div>
            </Space>
          </Card>
        )}
      </Space>

      {/* Callback Test Modal */}
      <Modal
        title="Test Callback Handling"
        open={callbackModalVisible}
        onCancel={() => setCallbackModalVisible(false)}
        onOk={() => callbackForm.submit()}
        confirmLoading={callbackLoading}
        width={700}
      >
        <Space direction="vertical" size="large" style={{ width: '100%' }}>
          <Alert
            message="Callback URL Received"
            description={extractedToken 
              ? "Token successfully extracted from callback URL. Verify the token to complete the flow test."
              : "Redirect URL received. If using cookie delivery, the token is stored in a secure cookie."
            }
            type="info"
            showIcon
          />

          <Form
            form={callbackForm}
            layout="vertical"
            onFinish={handleCallbackTest}
          >
            <Form.Item
              name="app_id"
              label="Application ID"
            >
              <Input readOnly />
            </Form.Item>

            <Form.Item
              name="token"
              label="Token from Callback"
              rules={[{ required: true, message: 'Token is required' }]}
            >
              <TextArea
                rows={3}
                style={{ fontFamily: 'monospace' }}
                placeholder="Token extracted from callback URL"
              />
            </Form.Item>

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

export default TokenTester;
