// Modal.js
import React, { useState, useEffect } from 'react';
import API from '../../api';
import {
  TextInput,
  Button,
  Modal,
  Flex,
  Select,
  PasswordInput,
  Group,
  Stack,
  MultiSelect,
  ActionIcon,
  Switch,
  Box,
  Tooltip,
  Grid,
  SimpleGrid,
  NumberInput,
  useMantineTheme,
} from '@mantine/core';
import { RotateCcwKey, RotateCw, X } from 'lucide-react';
import { Copy, Key } from 'lucide-react';
import { useForm } from '@mantine/form';
import useChannelsStore from '../../store/channels';
import { USER_LEVELS, USER_LEVEL_LABELS } from '../../constants';
import useAuthStore from '../../store/auth';
import { copyToClipboard } from '../../utils';

const User = ({ user = null, isOpen, onClose }) => {
  const profiles = useChannelsStore((s) => s.profiles);
  const authUser = useAuthStore((s) => s.user);
  const setUser = useAuthStore((s) => s.setUser);

  const [, setEnableXC] = useState(false);
  const [selectedProfiles, setSelectedProfiles] = useState(new Set());
  const [generating, setGenerating] = useState(false);
  const [generatedKey, setGeneratedKey] = useState(null);
  const [userAPIKey, setUserAPIKey] = useState(user?.api_key || null);

  const theme = useMantineTheme();

  const form = useForm({
    mode: 'uncontrolled',
    initialValues: {
      username: '',
      first_name: '',
      last_name: '',
      email: '',
      user_level: '0',
      stream_limit: 0,
      password: '',
      xc_password: '',
      channel_profiles: [],
      hide_adult_content: false,
    },

    validate: (values) => ({
      username: !values.username
        ? 'Username is required'
        : values.user_level == USER_LEVELS.STREAMER &&
            !values.username.match(/^[a-z0-9]+$/i)
          ? 'Streamer username must be alphanumeric'
          : null,
      password:
        !user && !values.password && values.user_level != USER_LEVELS.STREAMER
          ? 'Password is requried'
          : null,
      xc_password:
        values.xc_password && !values.xc_password.match(/^[a-z0-9]+$/i)
          ? 'XC password must be alphanumeric'
          : null,
    }),
  });

  const onChannelProfilesChange = (values) => {
    let newValues = new Set(values);
    if (selectedProfiles.has('0')) {
      newValues.delete('0');
    } else if (newValues.has('0')) {
      newValues = new Set(['0']);
    }

    setSelectedProfiles(newValues);

    form.setFieldValue('channel_profiles', [...newValues]);
  };

  const onSubmit = async () => {
    const values = form.getValues();

    const customProps = user?.custom_properties || {};

    // Always save xc_password, even if it's empty (to allow clearing)
    customProps.xc_password = values.xc_password || '';
    delete values.xc_password;

    // Save hide_adult_content in custom_properties
    customProps.hide_adult_content = values.hide_adult_content || false;
    delete values.hide_adult_content;

    values.custom_properties = customProps;

    // If 'All' is included, clear this and we assume access to all channels
    if (values.channel_profiles.includes('0')) {
      values.channel_profiles = [];
    }

    if (!user && values.user_level == USER_LEVELS.STREAMER) {
      // Generate random password - they can't log in, but user can't be created without a password
      values.password = Math.random().toString(36).slice(2);
    }

    if (!user) {
      await API.createUser(values);
    } else {
      if (!values.password) {
        delete values.password;
      }

      const response = await API.updateUser(
        user.id,
        values,
        isAdmin ? false : authUser.id === user.id
      );

      if (user.id == authUser.id) {
        setUser(response);
      }
    }

    form.reset();
    setUserAPIKey(null);
    onClose();
  };

  useEffect(() => {
    if (user?.id) {
      const customProps = user.custom_properties || {};

      form.setValues({
        username: user.username,
        first_name: user.first_name || '',
        last_name: user.last_name || '',
        email: user.email,
        user_level: `${user.user_level}`,
        stream_limit: user.stream_limit || 0,
        channel_profiles:
          user.channel_profiles.length > 0
            ? user.channel_profiles.map((id) => `${id}`)
            : ['0'],
        xc_password: customProps.xc_password || '',
        hide_adult_content: customProps.hide_adult_content || false,
      });

      if (customProps.xc_password) {
        setEnableXC(true);
      }

      setUserAPIKey(user.api_key || null);
    } else {
      form.reset();
    }
  }, [user]);

  const generateXCPassword = () => {
    form.setValues({
      xc_password: Math.random().toString(36).slice(2),
    });
  };

  if (!isOpen) {
    return <></>;
  }

  const isAdmin = authUser.user_level == USER_LEVELS.ADMIN;
  const isEditingSelf = authUser.id === user?.id;
  const showPermissions = isAdmin && !isEditingSelf;

  const canGenerateKey =
    authUser.user_level == USER_LEVELS.ADMIN || authUser.id === user?.id;

  const onGenerateKey = async () => {
    if (!canGenerateKey) {
      return;
    }

    setGenerating(true);
    try {
      const payload = {};
      if (authUser.user_level == USER_LEVELS.ADMIN && user?.id) {
        payload.user_id = user.id;
      }

      const resp = await API.generateApiKey(payload);
      const newKey = resp && (resp.key || resp.raw_key);
      if (newKey) {
        setGeneratedKey(newKey);
        setUserAPIKey(newKey);
      }
    } catch (e) {
      // API shows notifications
    } finally {
      setGenerating(false);
    }
  };

  const onRevokeKey = async () => {
    if (!canGenerateKey) return;

    setGenerating(true);
    try {
      const payload = {};
      if (authUser.user_level == USER_LEVELS.ADMIN && user?.id) {
        payload.user_id = user.id;
      }

      const resp = await API.revokeApiKey(payload);
      // backend returns { success: true } - clear local state
      if (resp && resp.success) {
        setGeneratedKey(null);
        setUserAPIKey(null);

        // If we're revoking the current authenticated user's key, update auth store
        if (user?.id && authUser?.id === user.id) {
          setUser({ ...authUser, api_key: null });
        }
      }
    } catch (e) {
      // API shows notifications
    } finally {
      setGenerating(false);
    }
  };

  return (
    <Modal opened={isOpen} onClose={onClose} title="User" size="xl">
      <form onSubmit={form.onSubmit(onSubmit)}>
        <Group justify="space-between" align="top">
          <Stack gap="xs" style={{ flex: 1 }}>
            <TextInput
              id="username"
              name="username"
              label="Username"
              disabled={!isAdmin}
              {...form.getInputProps('username')}
              key={form.key('username')}
            />

            <TextInput
              id="first_name"
              name="first_name"
              label="First Name"
              {...form.getInputProps('first_name')}
              key={form.key('first_name')}
            />

            <PasswordInput
              label="Password"
              description="Used for UI authentication"
              {...form.getInputProps('password')}
              key={form.key('password')}
              disabled={form.getValues().user_level == USER_LEVELS.STREAMER}
            />

            {showPermissions && (
              <>
                <Select
                  label="User Level"
                  data={Object.entries(USER_LEVELS).map(([, value]) => {
                    return {
                      label: USER_LEVEL_LABELS[value],
                      value: `${value}`,
                    };
                  })}
                  {...form.getInputProps('user_level')}
                  key={form.key('user_level')}
                />

                <NumberInput
                  label="Stream Limit (0 = unlimited)"
                  {...form.getInputProps('stream_limit')}
                  key={form.key('stream_limit')}
                />
              </>
            )}
          </Stack>

          <Stack gap="xs" style={{ flex: 1 }}>
            <TextInput
              id="email"
              name="email"
              label="E-Mail"
              {...form.getInputProps('email')}
              key={form.key('email')}
            />

            <TextInput
              id="last_name"
              name="last_name"
              label="Last Name"
              {...form.getInputProps('last_name')}
              key={form.key('last_name')}
            />

            <TextInput
              label="XC Password"
              description="Clear to disable XC API"
              {...form.getInputProps('xc_password')}
              key={form.key('xc_password')}
              rightSectionWidth={30}
              rightSection={
                <ActionIcon
                  variant="transparent"
                  size="sm"
                  color="white"
                  onClick={generateXCPassword}
                >
                  <RotateCcwKey />
                </ActionIcon>
              }
            />

            {showPermissions && (
              <MultiSelect
                label="Channel Profiles"
                {...form.getInputProps('channel_profiles')}
                key={form.key('channel_profiles')}
                onChange={onChannelProfilesChange}
                data={Object.values(profiles).map((profile) => ({
                  label: profile.name,
                  value: `${profile.id}`,
                }))}
              />
            )}

            {showPermissions && (
              <Box>
                <Tooltip
                  label="Hide channels marked as mature content (admin users not affected)"
                  position="top"
                  withArrow
                >
                  <Switch
                    label="Hide Mature Content"
                    {...form.getInputProps('hide_adult_content', {
                      type: 'checkbox',
                    })}
                    key={form.key('hide_adult_content')}
                  />
                </Tooltip>
              </Box>
            )}

            {canGenerateKey && (
              <Stack>
                {userAPIKey && (
                  <TextInput
                    label="API Key"
                    disabled={true}
                    value={userAPIKey}
                    rightSection={
                      <ActionIcon
                        variant="transparent"
                        size="sm"
                        color="white"
                        onClick={() =>
                          copyToClipboard(userAPIKey, {
                            successTitle: 'API Key Copied!',
                            successMessage:
                              'The API Key has been copied to your clipboard.',
                          })
                        }
                      >
                        <Copy />
                      </ActionIcon>
                    }
                  />
                )}

                <Group gap="xs" grow>
                  <Button
                    leftSection={<Key size={14} />}
                    size="xs"
                    onClick={onGenerateKey}
                    loading={generating}
                    variant="light"
                    fullWidth
                  >
                    {userAPIKey ? 'Regenerate API Key' : 'Generate API Key'}
                  </Button>

                  {userAPIKey && (
                    <Button
                      leftSection={<X size={14} />}
                      size="xs"
                      onClick={onRevokeKey}
                      loading={generating}
                      color={theme.colors.red[5]}
                      variant="light"
                      fullWidth
                    >
                      Revoke API Key
                    </Button>
                  )}
                </Group>
              </Stack>
            )}
          </Stack>
        </Group>

        <Flex mih={50} gap="xs" justify="flex-end" align="flex-end">
          <Button
            type="submit"
            variant="contained"
            disabled={form.submitting}
            size="small"
          >
            Save
          </Button>
        </Flex>
      </form>
    </Modal>
  );
};

export default User;
