import * as React from 'react';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/router';
import Box from '@mui/material/Box';
import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import TextField, { TextFieldProps } from '@mui/material/TextField';
import FormControl from '@mui/material/FormControl';
import FormLabel from '@mui/material/FormLabel';
import FormHelperText from '@mui/material/FormHelperText';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import LoadingButton from '@mui/lab/LoadingButton';
import Skeleton from '@mui/material/Skeleton';
import { useSnackbar } from 'notistack';

import { Pages } from 'src/constants';
// import Editor from 'src/components/Editor/RichTextEditor';
import TiptapEditor from 'src/components/Editor/Tiptap';
import SeverityHelperButton from 'src/components/Button/SeverityDescBtn';
import {
  SEVERITY_LEVELS,
  Severitylevel,
  DEV_TIDB_IMPACTED_COMPONENTS,
  DEV_CLOUD_DEPLOYMENT_TYPES,
} from 'src/constants';
import axios from 'src/lib/axios';
import TiDBCloudClusterForm from 'src/components/NewRequestSection/TiDBCloudClusterSection';
import {
  ProjectItem,
  ClusterItem,
} from 'src/components/NewRequestSection/TiDBCloudClusterSection';
import { RequestForm } from 'pages/api/zendesk/v2/requests';
import logger from 'next-pino/logger';
import { OrgListItem } from 'src/types/cloud';
import { AttachmentItem, User, ZendeskOrganization } from 'src/types/zendesk';
import UploadAttachmentButton from 'src/components/Button/UploadAttachment';
import { CloudOrgPlan } from 'src/types/cloud';

import { zendeskDataState } from 'src/atom';
import { useRecoilValue } from 'recoil';

export default function SeveritySelection(props: {
  onChange: (
    event: SelectChangeEvent,
    options: {
      zendeskOrgId: number | null;
    }
  ) => void;
  cloudData: {
    org: OrgListItem;
    project: ProjectItem | null;
    cluster: ClusterItem | null;
  } | null;
  formType: 'TiDB Cloud' | 'TiDB';
}) {
  const { onChange, cloudData, formType } = props;

  const [userTags, setUserTags] = React.useState<string[]>([]);
  const [severity, setSeverity] = React.useState('');
  const [isLoading, setIsLoading] = React.useState(false);
  const [zendeskOrgId, setZendeskOrgId] = React.useState<number | null>(null);

  const zendeskData = useRecoilValue(zendeskDataState);
  const { enqueueSnackbar } = useSnackbar();
  const { t } = useTranslation();

  const handleSeverityChange = (event: SelectChangeEvent) => {
    setSeverity(event.target.value);
    onChange(event, { zendeskOrgId });
  };

  React.useEffect(() => {
    const fetchMe = async () => {
      try {
        const res: { user: User } = await axios
          .get('/api/zendesk/v2/me', {
            headers: {
              Authorization: `${zendeskData.token}`,
            },
          })
          .then((res) => res.data);
        return res.user;
      } catch (error: any) {
        logger.error(
          { error, name: `NewRequestSection/SeveritySelection` },
          `Failed to fetch me`
        );
        enqueueSnackbar(error?.response?.data?.message || `${error}`, {
          variant: 'error',
        });
      }
    };
    const fetchUserOrgTags = async (cloudOrgId?: string) => {
      setIsLoading(true);

      try {
        const user = await fetchMe();
        if (!user?.id) return;

        // if (cloudOrgId) {
        //   const data: {
        //     data: null | Partial<ZendeskOrganization>;
        //   } = await axios
        //     .get(
        //       `/api/zendesk/v2/organizations/search?external_id=${cloudOrgId}`,
        //       {
        //         headers: {
        //           Authorization: `${zendeskData.token}`,
        //         },
        //       }
        //     )
        //     .then((res) => res.data);
        //   const tags = data.data?.tags || [];
        //   const targetZendeskOrgId = data.data?.id || null;
        //   targetZendeskOrgId && setZendeskOrgId(targetZendeskOrgId);
        //   setUserTags(tags);
        // } else {
        const data = await axios
          .get(`/api/zendesk/v2/users/${user.id}?field=organization_id`, {
            headers: {
              Authorization: `${zendeskData.token}`,
            },
          })
          .then((res) => res.data);
        const zendeskOrgId = data.organization_id as string;
        if (!zendeskOrgId) {
          // throw new Error('zendeskOrgId is empty');
          logger.warn(
            {
              name: `NewRequestSection/SeveritySelection`,
              user: user,
            },
            `User's zendesk org id is empty`
          );
          setUserTags([]);
          return;
        }
        const orgData = await axios
          .get(`/api/zendesk/v2/organizations/${zendeskOrgId}?field=tags`, {
            headers: {
              Authorization: `${zendeskData.token}`,
            },
          })
          .then((res) => res.data);
        const orgTags = (orgData.tags as string[]) || [];
        setUserTags(orgTags);
        // TODO: check op user's org tags; post cloud user ticket with zendesk org id(external_id binding)
        // }
      } catch (error: any) {
        logger.error(
          { error, name: `NewRequestSection/SeveritySelection` },
          `Failed to fetch user tags`
        );
        setUserTags([]);
        enqueueSnackbar(error?.response?.data?.message || `${error}`, {
          variant: 'error',
        });
      } finally {
        setIsLoading(false);
      }
    };

    if (zendeskData.token) {
      fetchUserOrgTags(cloudData?.org.id);
    }
  }, [zendeskData.token, cloudData?.org.id]);

  return (
    <>
      <FormControl
        id="tidb_form_serverity"
        size="small"
        sx={{
          display: 'flex',
          flexDirection: 'column',
          gap: '0.5rem',
        }}
      >
        <Box
          sx={{
            display: 'flex',
            gap: '0.5rem',
            alignItems: 'center',
          }}
        >
          <FormLabel>{`*` + t('new_request.tidb_serverity')}</FormLabel>
          <SeverityHelperButton />
        </Box>
        {isLoading && (
          <Skeleton variant="rounded" animation="wave" height={40} />
        )}
        {!isLoading && (
          <Select value={severity} onChange={handleSeverityChange} displayEmpty>
            {SEVERITY_LEVELS.map((item) => {
              // TODO: re-check in backend
              const judgeIfDisabled = (src: Severitylevel) => {
                // TiDB Cloud ticket
                if (formType === 'TiDB Cloud') {
                  if (src === Severitylevel.Critical) {
                    return cloudData?.cluster?.status
                      ? cloudData?.cluster?.status === 'NORMAL'
                      : true;
                  }
                  // Free plan user can only open Low severity ticket
                  if (
                    ['FREE_TRIAL', 'NEW_USER'].includes(
                      cloudData?.org?.plan || ''
                    )
                  ) {
                    return src !== Severitylevel.Low;
                  }
                  return false;
                }
                // TiDB ticket
                if (calcIntercetion(S1_TAGS, userTags).length > 0) {
                  return false;
                }
                return src === Severitylevel.Critical;
              };
              const shouldBeDisabled = judgeIfDisabled(item.id);

              return (
                <MenuItem
                  key={item.id}
                  value={`${item.id}`}
                  disabled={shouldBeDisabled}
                >
                  {t(`severity.${item.transKey}`)}
                  {` (S${item.id})`}
                </MenuItem>
              );
            })}
            <MenuItem value="">-</MenuItem>
          </Select>
        )}
      </FormControl>
    </>
  );
}

function calcIntercetion(array1: string[], array2: string[]) {
  const filteredArray = array1.filter((value: string) =>
    array2.includes(value)
  );
  return filteredArray;
}

const S1_TAGS = ['premium', 'enterprise', 'standard'];
