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 { useSnackbar } from 'notistack';
import Paper from '@mui/material/Paper';

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 } from 'src/types/zendesk';
import UploadAttachmentButton from 'src/components/Button/UploadAttachment';
import SeveritySelection from 'src/components/NewRequestSection/SeveritySelection';

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

export function CustomTextField(props: TextFieldProps) {
  const { label, ...other } = props;
  return (
    <Box
      sx={{
        display: 'flex',
        flexDirection: 'column',
        gap: '0.5rem',
      }}
    >
      <FormLabel>
        {other?.required ? `*` : ``}
        {props.label}
      </FormLabel>
      <TextField {...other} />
    </Box>
  );
}

export interface FormProps {
  type: 'TiDB' | 'TiDB Cloud';
}

export default function TiDBFormSection(props: FormProps) {
  const { type: formType } = props;

  const [ccEmails, setCCEmails] = React.useState<string[]>([]);
  const [isCCEmailsValid, setIsCCEmailsValid] = React.useState(true);
  const [subjectDetails, setSubjectDetails] = React.useState('');
  const [isSubjectDetailsFirstLoad, setIsSubjectDetailsFirstLoad] =
    React.useState(true);
  const [isSubjectDetailsValid, setIsSubjectDetailsValid] =
    React.useState(false);
  const [isdescObjFirstLoad, setIsdescObjFirstLoad] = React.useState(true);
  const [descObj, setDescObj] = React.useState({
    text: '',
    html: '',
  });
  const [TiDBVersion, setTiDBVersion] = React.useState('');
  const [isTiDBVersionValid, setIsTiDBVersionValid] = React.useState(true);
  const [severity, setSeverity] = React.useState('');
  const [TiDBComponent, setTiDBComponent] = React.useState('');
  const [cloudDeployment, setCloudDeployment] = React.useState('unknown');
  const [isTiDBDown, setIsTiDBDown] = React.useState(false);
  const [attachmentTokens, setAttachmentTokens] = React.useState<
    {
      token: string;
      attachment: AttachmentItem;
    }[]
  >([]);
  const [cloudData, setCloudData] = React.useState<{
    org: OrgListItem;
    project: ProjectItem | null;
    cluster: ClusterItem | null;
  } | null>(null);
  const [isSubmitting, setIsSubmitting] = React.useState(false);
  const [isFormValid, setIsFormValid] = React.useState(true);
  const [zendeskOrgId, setZendeskOrgId] = React.useState<number | null>(null);

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

  const handleCCEmailsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const value = event.target.value?.trim() || '';
    if (value === '') {
      setCCEmails([]);
      setIsCCEmailsValid(true);
    } else {
      const emails = value.split(',').map((i) => i.trim());
      const isValid = emails.every((email) => {
        return email.match(/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i);
      });
      setIsCCEmailsValid(isValid);
      setCCEmails(emails);
    }
  };

  const handleSubjectDetailsChange = (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const value = event.target.value?.trim() || '';
    isSubjectDetailsFirstLoad && setIsSubjectDetailsFirstLoad(false);
    if (value === '') {
      setSubjectDetails('');
      setIsSubjectDetailsValid(false);
    } else {
      setIsSubjectDetailsValid(true);
      setSubjectDetails(value);
    }
  };

  const handleEditorChnage = ({
    text,
    html,
  }: {
    text: string;
    html: string;
  }) => {
    isdescObjFirstLoad && setIsdescObjFirstLoad(false);
    setDescObj({ text, html });
  };

  const handleFormTiDBVerChange = (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    const re = /^v\d(\.\d){0,1}(\.\d)$/;
    event.target.value
      ? setIsTiDBVersionValid(re.test(event.target.value))
      : setIsTiDBVersionValid(true);
    setTiDBVersion(event.target.value);
  };

  const handleSeverityChange = (
    event: SelectChangeEvent,
    options: {
      zendeskOrgId: number | null;
    }
  ) => {
    setSeverity(event.target.value);
    options.zendeskOrgId && setZendeskOrgId(options.zendeskOrgId);
  };

  const handleComponentChange = (event: SelectChangeEvent) => {
    setTiDBComponent(event.target.value);
  };

  const handleCloudDeploymentChange = (event: SelectChangeEvent) => {
    setCloudDeployment(event.target.value);
  };

  const handleIsTiDBDownChange = (
    event: React.ChangeEvent<HTMLInputElement>
  ) => {
    setIsTiDBDown(event.target.checked);
  };

  const handleCloudFormChange = (data: {
    org: OrgListItem | null;
    project: ProjectItem | null;
    cluster: ClusterItem | null;
  }) => {
    const { org, project, cluster } = data;
    if (org || project || cluster) {
      setCloudData(
        data as {
          org: OrgListItem;
          project: ProjectItem | null;
          cluster: ClusterItem | null;
        }
      );
    } else {
      setCloudData(null);
    }
  };

  const handleSubmitRequest = async () => {
    setIsSubmitting(true);
    const requestForm: RequestForm = {
      subject: `[${formType}] ${subjectDetails}`,
      body: descObj.html,
      type: 'html',
      severity:
        SEVERITY_LEVELS.find((i) => `${i.id}` === severity)?.value || '',
      emails: ccEmails,
      uploads: attachmentTokens.map((i) => i.token),
      isDown: isTiDBDown,
      component: TiDBComponent,
      version: TiDBVersion,
      organizationId: zendeskOrgId,
    };
    if (formType === 'TiDB Cloud') {
      requestForm.cloud = {
        orgId: cloudData?.org?.id || '',
        projectId: cloudData?.project?.id || '',
        clusterId: cloudData?.cluster?.id || '',
        orgName: cloudData?.org?.name || '',
        projectName: cloudData?.project?.name || '',
        clusterName: cloudData?.cluster?.name || '',
        plan: cloudData?.org?.plan || '',
        clusterStatus: cloudData?.cluster?.status || '',
        deployment: cloudDeployment,
      };
    }

    try {
      await axios.post(
        `/api/zendesk/v2/requests`,
        {
          request: requestForm,
        },
        {
          headers: {
            Authorization: `${zendeskData.token}`,
          },
        }
      );
      router.push(Pages.Requests);
    } catch (error: any) {
      logger.error(
        { error, name: `NewRequestSection/Form` },
        `Failed to submit request`
      );
      enqueueSnackbar(error, { variant: 'error' });
    } finally {
      setIsSubmitting(false);
    }
  };

  React.useEffect(() => {
    if (cloudData) {
      const { org, project, cluster } = cloudData;
      org?.plan === 'FREE_TRIAL' && setSeverity('');
      setTiDBVersion(cluster?.version || '');
    }
  }, [cloudData]);

  React.useEffect(() => {
    const isTiDBFormCompleted =
      isSubjectDetailsValid &&
      isCCEmailsValid &&
      descObj.text &&
      severity &&
      TiDBComponent &&
      isTiDBVersionValid;
    switch (formType) {
      case 'TiDB':
        if (isTiDBFormCompleted) {
          setIsFormValid(true);
        } else {
          setIsFormValid(false);
        }
        break;
      case 'TiDB Cloud':
        if (cloudData && isTiDBFormCompleted) {
          setIsFormValid(true);
        } else {
          setIsFormValid(false);
        }
        break;
      default:
        break;
    }
  }, [
    TiDBComponent,
    cloudData,
    descObj.text,
    formType,
    isCCEmailsValid,
    isSubjectDetailsValid,
    severity,
    isTiDBVersionValid,
  ]);

  return (
    <>
      <Typography variant="h5" component="h1">
        {t('new_request.title')}
      </Typography>
      <Paper
        elevation={3}
        sx={{
          p: '1.5rem',
        }}
      >
        <Box
          sx={{
            display: 'flex',
            flexDirection: 'column',
            gap: '1rem',
          }}
        >
          <CustomTextField
            id="tidb_form_type"
            label={t('new_request.support_type')}
            required
            defaultValue={formType}
            size="small"
            fullWidth
            disabled
            InputProps={{
              readOnly: true,
            }}
          />

          <CustomTextField
            id="tidb_form_cc"
            label={t('new_request.cc_optional')}
            size="small"
            fullWidth
            placeholder={t('new_request.cc_optional_placeholder')}
            onChange={handleCCEmailsChange}
            error={!isCCEmailsValid}
            helperText={
              !isCCEmailsValid && t('new_request.cc_optional_error_msg')
            }
          />

          <CustomTextField
            id="tidb_form_subject"
            label={t('new_request.subject')}
            required
            size="small"
            fullWidth
            onChange={handleSubjectDetailsChange}
            error={isSubjectDetailsFirstLoad ? false : !isSubjectDetailsValid}
            helperText={
              !isSubjectDetailsValid && t('new_request.empty_error_message')
            }
          />

          <Box
            id="tidb_form_description"
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '0.5rem',
            }}
          >
            <FormLabel>{`*` + t('new_request.description')}</FormLabel>
            {/* <Editor onChange={handleEditorChnage} /> */}
            <TiptapEditor onChange={handleEditorChnage} />
            <FormHelperText
              sx={{
                ml: '14px',
              }}
              error={isdescObjFirstLoad ? false : !descObj.text}
            >
              {descObj.text
                ? t('new_request.description_helper_text')
                : t('new_request.empty_error_message')}
            </FormHelperText>
          </Box>

          {/* TiDB/TiDB Cloud Version */}
          {formType === 'TiDB Cloud' && (
            <TiDBCloudClusterForm onChange={handleCloudFormChange} />
          )}

          <CustomTextField
            id="tidb_form_version"
            label={t('new_request.tidb_version_optional')}
            size="small"
            fullWidth
            value={TiDBVersion}
            onChange={handleFormTiDBVerChange}
            error={!isTiDBVersionValid}
            helperText={
              formType === 'TiDB Cloud'
                ? ``
                : isTiDBVersionValid
                ? t('new_request.tidb_version_optional_helper_text')
                : t('new_request.tidb_version_optional_helper_text_error')
            }
            disabled={formType === 'TiDB Cloud'}
          />

          <SeveritySelection
            onChange={handleSeverityChange}
            cloudData={cloudData}
            formType={formType}
          />

          {formType === 'TiDB Cloud' && (
            <FormControl
              id="cloud_form_deployment"
              size="small"
              sx={{
                display: 'flex',
                flexDirection: 'column',
                gap: '0.5rem',
              }}
            >
              <FormLabel>
                {`*` + t('new_request.cloud_deployment_type')}
              </FormLabel>
              <Select
                value={cloudDeployment}
                onChange={handleCloudDeploymentChange}
                displayEmpty
              >
                {DEV_CLOUD_DEPLOYMENT_TYPES.map((item) => (
                  <MenuItem key={item.id} value={item.value}>
                    {item.name}
                  </MenuItem>
                ))}
              </Select>
            </FormControl>
          )}

          <FormControl
            id="tidb_form_component"
            size="small"
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '0.5rem',
            }}
          >
            <FormLabel>{`*` + t('new_request.tidb_component')}</FormLabel>
            <Select
              value={TiDBComponent}
              onChange={handleComponentChange}
              displayEmpty
            >
              {DEV_TIDB_IMPACTED_COMPONENTS.map((item) => (
                <MenuItem key={item.id} value={item.value}>
                  {item.name}
                </MenuItem>
              ))}
              <MenuItem value="">-</MenuItem>
            </Select>
          </FormControl>

          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '0.5rem',
            }}
          >
            <FormLabel>{t('new_request.tidb_down_optional')}</FormLabel>
            <FormControlLabel
              control={
                <Checkbox
                  onChange={handleIsTiDBDownChange}
                  checked={isTiDBDown}
                />
              }
              label={t('new_request.tidb_is_down')}
              sx={{
                width: 'fit-content',
              }}
            />
          </Box>

          <Box
            sx={{
              display: 'flex',
              flexDirection: 'column',
              gap: '0.5rem',
            }}
          >
            <FormLabel>{t('new_request.attachments_optional')}</FormLabel>
            <UploadAttachmentButton
              onChange={(items) => {
                setAttachmentTokens(items);
              }}
            />
          </Box>
        </Box>
        <Box
          sx={{
            width: '100%',
            paddingTop: '1.5rem',
          }}
        >
          <LoadingButton
            variant="contained"
            onClick={handleSubmitRequest}
            loading={isSubmitting}
            disabled={!isFormValid}
            sx={{
              width: '100%',
            }}
          >
            {t('new_request.submit_button')}
          </LoadingButton>
        </Box>
      </Paper>
    </>
  );
}
