import React, { useState, useEffect } from 'react';
import {
  Table,
  Button,
  Stack,
  Title,
  Modal,
  TextInput,
  MultiSelect,
  Group,
  ActionIcon,
  Badge,
  Card,
  Text,
  Loader,
  Alert,
  Select,
  Textarea,
  Code,
  Divider,
} from '@mantine/core';
import {
  IconPlus,
  IconTrash,
  IconEye,
  IconCopy,
  IconAlertCircle,
  IconKey,
  IconCheck,
} from '@tabler/icons-react';
import { useForm } from '@mantine/form';
import { notifications } from '@mantine/notifications';
import {
  apiService,
  Application,
  StaticToken,
  CreateTokenRequest,
  CreateTokenResponse,
} from '../services/apiService';
import dayjs from 'dayjs';

interface TokenWithApp extends StaticToken {
  app?: Application;
}

const Tokens: React.FC = () => {
  const [applications, setApplications] = useState<Application[]>([]);
  const [tokens, setTokens] = useState<TokenWithApp[]>([]);
  const [loading, setLoading] = useState(false);
  const [modalOpen, setModalOpen] = useState(false);
  const [tokenModalOpen, setTokenModalOpen] = useState(false);
  const [createdToken, setCreatedToken] = useState<CreateTokenResponse | null>(null);

  const form = useForm<CreateTokenRequest & { app_id: string }>({
    initialValues: {
      app_id: '',
      owner: {
        type: 'user',
        name: 'Admin User',
        owner: 'admin@example.com',
      },
      permissions: [],
    },
    validate: {
      app_id: (value) => value.length < 1 ? 'Application is required' : null,
      permissions: (value) => value.length < 1 ? 'At least one permission is required' : null,
    },
  });

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

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

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

  const loadAllTokens = async () => {
    try {
      setLoading(true);
      const appsResponse = await apiService.getApplications(100, 0);
      const allTokens: TokenWithApp[] = [];

      // Load tokens for each application
      for (const app of appsResponse.data) {
        try {
          const tokensResponse = await apiService.getTokensForApplication(app.app_id, 100, 0);
          const tokensWithApp = tokensResponse.data.map(token => ({
            ...token,
            app,
          }));
          allTokens.push(...tokensWithApp);
        } catch (error) {
          // Some apps might not have tokens, that's OK
        }
      }

      setTokens(allTokens);
    } catch (error) {
      console.error('Failed to load tokens:', error);
      notifications.show({
        title: 'Error',
        message: 'Failed to load tokens',
        color: 'red',
      });
    } finally {
      setLoading(false);
    }
  };

  const handleSubmit = async (values: CreateTokenRequest & { app_id: string }) => {
    try {
      const { app_id, ...tokenData } = values;
      const response = await apiService.createToken(app_id, tokenData);
      setCreatedToken(response);
      setModalOpen(false);
      setTokenModalOpen(true);
      form.reset();
      loadAllTokens();
      notifications.show({
        title: 'Success',
        message: 'Token created successfully',
        color: 'green',
      });
    } catch (error) {
      console.error('Failed to create token:', error);
      notifications.show({
        title: 'Error',
        message: 'Failed to create token',
        color: 'red',
      });
    }
  };

  const handleDelete = async (tokenId: string) => {
    if (window.confirm('Are you sure you want to delete this token? This action cannot be undone.')) {
      try {
        await apiService.deleteToken(tokenId);
        notifications.show({
          title: 'Success',
          message: 'Token deleted successfully',
          color: 'green',
        });
        loadAllTokens();
      } catch (error) {
        console.error('Failed to delete token:', error);
        notifications.show({
          title: 'Error',
          message: 'Failed to delete token',
          color: 'red',
        });
      }
    }
  };

  const copyToClipboard = (text: string) => {
    navigator.clipboard.writeText(text);
    notifications.show({
      title: 'Copied',
      message: 'Copied to clipboard',
      color: 'blue',
    });
  };

  const rows = tokens.map((token) => (
    <Table.Tr key={token.id}>
      <Table.Td>
        <Group gap="xs">
          <IconKey size={16} color="blue" />
          <Text size="sm" style={{ fontFamily: 'monospace' }}>
            {token.id.substring(0, 8)}...
          </Text>
        </Group>
      </Table.Td>
      <Table.Td>
        <Badge variant="light" color="blue">
          {token.app?.app_id || 'Unknown'}
        </Badge>
      </Table.Td>
      <Table.Td>
        <Text size="sm" c="dimmed">
          {token.owner.name} ({token.owner.owner})
        </Text>
      </Table.Td>
      <Table.Td>
        <Badge variant="light" color="green">
          {token.type}
        </Badge>
      </Table.Td>
      <Table.Td>
        <Text size="sm">
          {dayjs(token.created_at).format('MMM DD, YYYY')}
        </Text>
      </Table.Td>
      <Table.Td>
        <Group gap="xs">
          <ActionIcon
            variant="subtle"
            color="blue"
            onClick={() => copyToClipboard(token.id)}
            title="Copy Token ID"
          >
            <IconCopy size={16} />
          </ActionIcon>
          <ActionIcon
            variant="subtle"
            color="red"
            onClick={() => handleDelete(token.id)}
            title="Delete Token"
          >
            <IconTrash size={16} />
          </ActionIcon>
        </Group>
      </Table.Td>
    </Table.Tr>
  ));

  return (
    <Stack gap="lg">
      <Group justify="space-between">
        <div>
          <Title order={2} mb="xs">
            API Tokens
          </Title>
          <Text c="dimmed">
            Manage static API tokens for your applications
          </Text>
        </div>
        <Button
          leftSection={<IconPlus size={16} />}
          onClick={() => {
            form.reset();
            setModalOpen(true);
          }}
          disabled={applications.length === 0}
        >
          Create Token
        </Button>
      </Group>

      {applications.length === 0 && (
        <Alert
          icon={<IconAlertCircle size={16} />}
          title="No Applications Found"
          color="yellow"
        >
          You need to create at least one application before you can create tokens.
        </Alert>
      )}

      {loading ? (
        <Stack align="center" justify="center" h={200}>
          <Loader size="lg" />
          <Text>Loading tokens...</Text>
        </Stack>
      ) : tokens.length === 0 ? (
        <Card shadow="sm" radius="md" withBorder p="xl">
          <Stack align="center" gap="md">
            <IconKey size={48} color="gray" />
            <div style={{ textAlign: 'center' }}>
              <Text fw={500} mb="xs">
                No tokens found
              </Text>
              <Text size="sm" c="dimmed">
                Create your first API token to start using the key management system
              </Text>
            </div>
            {applications.length > 0 && (
              <Button
                leftSection={<IconPlus size={16} />}
                onClick={() => {
                  form.reset();
                  setModalOpen(true);
                }}
              >
                Create Token
              </Button>
            )}
          </Stack>
        </Card>
      ) : (
        <Card shadow="sm" radius="md" withBorder>
          <Table>
            <Table.Thead>
              <Table.Tr>
                <Table.Th>Token ID</Table.Th>
                <Table.Th>Application</Table.Th>
                <Table.Th>Owner</Table.Th>
                <Table.Th>Type</Table.Th>
                <Table.Th>Created</Table.Th>
                <Table.Th>Actions</Table.Th>
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>{rows}</Table.Tbody>
          </Table>
        </Card>
      )}

      {/* Create Token Modal */}
      <Modal
        opened={modalOpen}
        onClose={() => {
          setModalOpen(false);
          form.reset();
        }}
        title="Create New Token"
        size="md"
      >
        <form onSubmit={form.onSubmit(handleSubmit)}>
          <Stack gap="md">
            <Select
              label="Application"
              placeholder="Select an application"
              required
              data={applications.map(app => ({
                value: app.app_id,
                label: `${app.app_id} (${app.type.join(', ')})`,
              }))}
              {...form.getInputProps('app_id')}
            />

            <MultiSelect
              label="Permissions"
              placeholder="Select permissions for this token"
              required
              data={availablePermissions.map(perm => ({
                value: perm,
                label: perm,
              }))}
              {...form.getInputProps('permissions')}
              searchable
            />

            <TextInput
              label="Owner Name"
              placeholder="Token owner name"
              {...form.getInputProps('owner.name')}
            />

            <TextInput
              label="Owner Email"
              placeholder="owner@example.com"
              {...form.getInputProps('owner.owner')}
            />

            <Group justify="flex-end" mt="md">
              <Button
                variant="subtle"
                onClick={() => {
                  setModalOpen(false);
                  form.reset();
                }}
              >
                Cancel
              </Button>
              <Button type="submit">Create Token</Button>
            </Group>
          </Stack>
        </form>
      </Modal>

      {/* Token Created Modal */}
      <Modal
        opened={tokenModalOpen}
        onClose={() => {
          setTokenModalOpen(false);
          setCreatedToken(null);
        }}
        title="Token Created Successfully"
        size="lg"
      >
        {createdToken && (
          <Stack gap="md">
            <Alert
              icon={<IconCheck size={16} />}
              title="Important"
              color="green"
            >
              This is the only time you will see the full token. Make sure to copy and store it securely.
            </Alert>

            <div>
              <Text fw={500} mb="xs">Token:</Text>
              <Group gap="xs">
                <Code
                  block
                  style={{
                    fontSize: '12px',
                    wordBreak: 'break-all',
                    flex: 1,
                  }}
                >
                  {createdToken.token}
                </Code>
                <ActionIcon
                  variant="subtle"
                  color="blue"
                  onClick={() => copyToClipboard(createdToken.token)}
                  title="Copy Token"
                >
                  <IconCopy size={16} />
                </ActionIcon>
              </Group>
            </div>

            <Divider />

            <Group justify="space-between">
              <Text fw={500}>Token ID:</Text>
              <Group gap="xs">
                <Text size="sm" style={{ fontFamily: 'monospace' }}>
                  {createdToken.id}
                </Text>
                <ActionIcon
                  size="sm"
                  variant="subtle"
                  onClick={() => copyToClipboard(createdToken.id)}
                >
                  <IconCopy size={12} />
                </ActionIcon>
              </Group>
            </Group>

            <Group justify="space-between" align="flex-start">
              <Text fw={500}>Permissions:</Text>
              <Stack gap="xs" align="flex-end">
                {createdToken.permissions.map((perm) => (
                  <Badge key={perm} variant="light" size="sm">
                    {perm}
                  </Badge>
                ))}
              </Stack>
            </Group>

            <Group justify="space-between">
              <Text fw={500}>Created:</Text>
              <Text size="sm">
                {dayjs(createdToken.created_at).format('MMM DD, YYYY HH:mm')}
              </Text>
            </Group>

            <Group justify="flex-end" mt="lg">
              <Button
                onClick={() => {
                  setTokenModalOpen(false);
                  setCreatedToken(null);
                }}
              >
                Close
              </Button>
            </Group>
          </Stack>
        )}
      </Modal>
    </Stack>
  );
};

export default Tokens;