import { useState, useEffect, useRef } from 'react';

import Button from '../../components/common/button/Button';
import RadioInput from '../../components/common/input/Radio';

import styled from 'styled-components';
import { Title, BtnWrapper, TextInput, SelectInput, DatePickerWrapper, ButtonClose, ModalText } from '../../styles/Components';

import Modal from '../../components/common/modal/Modal';
import DatePickerComponent from '../../components/common/Date/DatePickerComponent';

import { authType, blockPeriod, blockSanctions, blockType, HourList, MinuteList } from '../../assets/data';
import DatePicker, { registerLocale } from 'react-datepicker';
import { ko } from 'date-fns/esm/locale';
import 'react-datepicker/dist/react-datepicker.css';
import { getMonth, getYear, setHours } from 'date-fns';
import range from 'lodash/range';
import { useNavigate } from 'react-router-dom';
import UserBlockUploadBtn from '../../components/ServiceManage/UserBlockUploadBtn';
import { BlackListRegist, BlackListMultipleUpload } from '../../apis';

import { authList } from '../../store/authList';
import { useRecoilValue } from 'recoil';
import AuthModal from '../../components/common/modal/AuthModal';

registerLocale('ko', ko);

const UserBlockRegist = () => {
	const token = sessionStorage.getItem('token');

	const navigate = useNavigate();
	const userInfo = useRecoilValue(authList);

	//시간 관련 변수
	const [sendHour, setSendHour] = useState('00');
	const [sendMin, setSendMin] = useState('00');
	const [endHour, setEndHour] = useState('00');
	const [endMin, setEndMin] = useState('00');

	const [selectData, setSelectData] = useState('single');
	const [selectSingle, setSelectSingle] = useState(false);
	const [selectMulti, setSelectMulti] = useState(true);
	const [startDate, setStartDate] = useState(null);
	const years = range(1990, getYear(new Date()) + 1, 1);
	const months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];

	const [registModalClose, setRegistModalClose] = useState('hidden');
	const [completeModalClose, setCompleteModalClose] = useState('hidden');
	const [isNullValue, setIsNullValue] = useState(false);

	const [guidList, setGuidList] = useState([]);
	const [typeError, setTypeError] = useState(true);
	const [resultData, setResultData] = useState({
		list: [{ guid: '' }],
		type: '',
		sanctions: '',
		period: '',
		start_dt: '',
		end_dt: '',
	});
	const [confirmText, setConfirmText] = useState('');

	const handleChange = e => {
		setSelectData(e.target.value);
		handleReset();
	};

	const handleReset = () => {
		setResultData({
			list: [{ guid: '' }],
			type: '',
			sanctions: '',
			period: '',
			start_dt: '',
			end_dt: '',
		});
	};

	const [previewModal, setPreviewModal] = useState('hidden');
	const handlePreview = e => {
		e.preventDefault();
		previewModal === 'hidden' ? setPreviewModal('view') : setPreviewModal('hidden');
	};

	useEffect(() => {
		if (selectData === 'single') {
			setSelectSingle(false);
			setSelectMulti(true);
			if (resultData.period === 'WARNING') {
				setEndHour('01');
			} else {
				setEndHour('00');
			}
		} else if (selectData === 'multi') {
			setSelectSingle(true);
			setSelectMulti(false);
			if (resultData.period === 'WARNING') {
				setEndHour('01');
			} else {
				setEndHour('00');
			}
		}
		let list = [];

		if (guidList) {
			guidList.map(data =>
				list.push({
					guid: data.guid,
					nickname: data.nickname,
				}),
			);
			setResultData({ ...resultData, list: list });
		}
	}, [selectData, guidList]);

	// 제재 시간 세팅 로직
	const handleSendTime = e => {
		let sendDate = new Date(resultData.start_dt);

		if (resultData.start_dt.length === 0) {
			sendDate = new Date();
		} else {
			sendDate = new Date(resultData.start_dt);
		}

		const result = new Date(sendDate.getFullYear(), sendDate.getMonth(), sendDate.getDate(), e.target.id === 'hour' ? e.target.value : sendHour, e.target.id === 'min' ? e.target.value : sendMin);

		const blockDay = resultData.period.slice(1) > 0 ? Number(resultData.period.slice(1)) : 0;
		const permanentDay = 2999 - sendDate.getFullYear();

		if (e.target.id === 'hour') setSendHour(e.target.value);
		else if (e.target.id === 'min') setSendMin(e.target.value);
		if (e.target.id === 'hour' && resultData.period === 'WARNING') {
			let targetHour = String(e.target.value);
			let plusHour = Number(e.target.value) + 1;

			if (targetHour < 9) {
				setEndHour('0' + String(plusHour));
			} else {
				setEndHour(plusHour);
			}
		} else if (resultData.period !== 'WARNING' && e.target.id === 'hour') {
			setEndHour(e.target.value);
		}

		if (resultData.period === 'WARNING') {
			const EndResult = new Date(
				sendDate.getFullYear(),
				sendDate.getMonth(),
				sendDate.getDate() + blockDay,
				e.target.id === 'hour' ? e.target.value : sendHour,
				e.target.id === 'min' ? e.target.value : sendMin + 60,
			);

			setResultData({ ...resultData, start_dt: result, end_dt: EndResult });
		} else if (resultData.period === 'PERMANENT') {
			const EndResult = new Date(
				sendDate.getFullYear() + permanentDay,
				sendDate.getMonth(),
				sendDate.getDate() + blockDay,
				e.target.id === 'hour' ? e.target.value : sendHour,
				e.target.id === 'min' ? e.target.value : sendMin,
			);

			setResultData({ ...resultData, start_dt: result, end_dt: EndResult });
		} else if (blockDay > 0) {
			const EndResult = new Date(
				sendDate.getFullYear(),
				sendDate.getMonth(),
				sendDate.getDate() + blockDay,
				e.target.id === 'hour' ? e.target.value : sendHour,
				e.target.id === 'min' ? e.target.value : sendMin,
			);

			setResultData({ ...resultData, start_dt: result, end_dt: EndResult });
		}
	};

	const handleSelectedDate = data => {
		setSendHour('00');
		setSendMin('00');
		setEndHour('00');

		const sendDate = new Date(data);
		const blockDay = Number(resultData.period.slice(1));
		const permanentDay = 2999 - sendDate.getFullYear();

		if (endHour === '00' && resultData.period === 'WARNING') {
			setEndHour('01');
		}

		const resultSendData = new Date(sendDate.getFullYear(), sendDate.getMonth(), sendDate.getDate(), sendHour, sendMin);

		if (blockDay > 0) {
			const resultEndData = new Date(sendDate.getFullYear(), sendDate.getMonth(), sendDate.getDate() + blockDay, sendHour, sendMin);
			setResultData({ ...resultData, start_dt: resultSendData, end_dt: resultEndData });
		} else if (resultData.period === 'PERMANENT') {
			const resultEndData = new Date(sendDate.getFullYear() + permanentDay, sendDate.getMonth(), sendDate.getDate(), sendHour, sendMin);
			setResultData({ ...resultData, start_dt: resultSendData, end_dt: resultEndData });
		} else if (resultData.period === 'WARNING') {
			const resultEndData = new Date(sendDate.getFullYear(), sendDate.getMonth(), sendDate.getDate(), sendHour, sendMin + 60);
			setResultData({ ...resultData, start_dt: resultSendData, end_dt: resultEndData });
		}
	};

	// 기간, 시간 초기화
	const setTimeValue = e => {
		setResultData({ ...resultData, period: e.target.value, start_dt: '', end_dt: '' });
		setSendMin('00');
		setSendHour('00');

		if (resultData.period === 'WARNING') setEndHour('01');
	};

	// 등록 확인 모달
	let notNull = resultData.list.length > 0 && resultData.type && resultData.period && resultData.sanctions && resultData.start_dt && resultData.end_dt;

	const handleRegistModalClose = () => {
		if(selectData === 'multi'){
			const guidChk = guidList.some(guid => guid.validate === false);
			if(guidChk) {
				alert("유효성 체크가 통과되지 않은 항목이 존재합니다. \r\n수정 후 재등록 해주세요.")
				return;
			}
		}

		if (notNull) {
			registModalClose === 'hidden' ? setRegistModalClose('view') : setRegistModalClose('hidden');
			setIsNullValue(false);
		} else {
			setIsNullValue(true);
		}
	};

	// 등록 완료 모달
	const handleCompleteModalClose = () => {
		if (completeModalClose === 'hidden') {
			setCompleteModalClose('view');
		} else {
			setCompleteModalClose('hidden');
			handleReset();
			handleRegistModalClose();

			navigate('/servicemanage/userblock');
			window.location.reload();
		}
	};

	// 등록 api 연동
	const handleRegist = async () => {
		const message = await BlackListRegist(token, resultData);

		message.data.data.message === '등록 하였습니다.' ? 
		setConfirmText('등록이 완료되었습니다.') :
		message.data.data.message === 'admindb_exit_error' ? 
		setConfirmText("이미 등록된 유저입니다.") : setConfirmText(message.data.data.message);

		handleRegistModalClose();
		handleCompleteModalClose();
	};

	// console.log('DataList: ', resultData);
	// console.log('resultData.period :', resultData.period);
	// console.log(resultData.period.length);

	return (
		<>
			{userInfo.auth_list && !userInfo.auth_list.some(auth => auth.id === authType.blackListUpdate) ? (
				<AuthModal/>
			) : (
				<>
					<Title>이용자 제재 등록</Title>

					<div>
						<RadioInput id="single" value="single" label="단일 등록" name="blockregist" fontSize="20px" fontWeight="500" checked={selectData === 'single'} handleChange={handleChange} />
						<RegistGroup>
							<InputItem>
								<Label>제재 대상</Label>
								<TextInput
									placeholder="GUID 입력"
									width="400px"
									disabled={selectSingle}
									value={resultData.list[0]?.guid || ''}
									onChange={e => {
										let list = [];
										list.push({ guid: e.target.value });
										setResultData({ ...resultData, list });
									}}
								/>
							</InputItem>
							<InputRow>
								<InputItem>
									<Label>제재 방식</Label>
									<SelectInput value={resultData.type} onChange={e => setResultData({ ...resultData, type: e.target.value })} disabled={selectSingle}>
										{blockType.map((data, index) => (
											<option key={index} value={data.value}>
												{selectData === 'single' ? data.name : '선택'}
											</option>
										))}
									</SelectInput>
								</InputItem>
								<InputItem>
									<Label>제재 기간</Label>
									<SelectInput value={resultData.period} onChange={e => setTimeValue(e)} disabled={selectSingle}>
										{blockPeriod.map((data, index) => (
											<option key={index} value={data.value}>
												{selectData === 'single' ? data.name : '선택'}
											</option>
										))}
									</SelectInput>
								</InputItem>
								<InputItem>
									<Label>제재 사유</Label>
									<SelectInput value={resultData.sanctions} onChange={e => setResultData({ ...resultData, sanctions: e.target.value })} disabled={selectSingle}>
										{blockSanctions.map((data, index) => (
											<option key={index} value={data.value}>
												{selectData === 'single' ? data.name : '선택'}
											</option>
										))}
									</SelectInput>
								</InputItem>
							</InputRow>
							<InputRow>
								<InputItem>
									<Label>시작 일시</Label>
									<InputGroup>
										<DatePickerWrapper>
											<DatePickerComponent
												name="시작 일자"
												handleSelectedDate={data => handleSelectedDate(data)}
												selectedDate={resultData.start_dt}
												disabled={selectSingle || !resultData.period}
												pastDate={new Date()}
											/>
										</DatePickerWrapper>
										<SelectInput onChange={e => handleSendTime(e)} id="hour" disabled={selectSingle || !resultData.period} value={sendHour}>
											{HourList.map(hour => (
												<option value={hour} key={hour}>
													{hour}
												</option>
											))}
										</SelectInput>
										<SelectInput onChange={e => handleSendTime(e)} id="min" disabled={selectSingle || !resultData.period} value={sendMin}>
											{MinuteList.map(min => (
												<option value={min} key={min}>
													{min}
												</option>
											))}
										</SelectInput>
									</InputGroup>
								</InputItem>
								<InputItem>
									<Label>만료 일시</Label>
									<InputGroup>
										<DatePickerWrapper>
											<DatePicker
												disabled
												selected={selectData === 'single' ? resultData.end_dt : ''}
												onChange={date => setStartDate(date)}
												className="datepicker"
												placeholderText="만료일자"
												calendarClassName="calendar"
												dateFormat="yyyy - MM - dd"
												locale="ko"
												renderCustomHeader={({ date, changeYear, changeMonth, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled }) => (
													<div className="calendar-top">
														<button
															className="btn-prev"
															onClick={e => {
																e.preventDefault();
																decreaseMonth();
															}}
															disabled={prevMonthButtonDisabled}></button>
														<select value={getYear(date)} onChange={({ target: { value } }) => changeYear(value)}>
															{years.map(option => (
																<option key={option} value={option}>
																	{option}
																</option>
															))}
														</select>
														.
														<select value={months[getMonth(date)]} onChange={({ target: { value } }) => changeMonth(months.indexOf(value))}>
															{months.map(option => (
																<option key={option} value={option}>
																	{option}
																</option>
															))}
														</select>
														<button
															className="btn-next"
															onClick={e => {
																e.preventDefault();
																increaseMonth();
															}}
															disabled={nextMonthButtonDisabled}></button>
													</div>
												)}
											/>
										</DatePickerWrapper>
										<SelectInput disabled>
											<option value="">{selectData === 'single' && resultData.start_dt ? endHour : '00'}</option>
										</SelectInput>
										<SelectInput disabled>
											<option value="">{selectData === 'single' && resultData.start_dt ? sendMin : '00'}</option>
										</SelectInput>
									</InputGroup>
								</InputItem>
							</InputRow>
						</RegistGroup>
					</div>

					<div>
						<RadioInput id="multi" value="multi" label="복수 등록" name="blockregist" fontSize="20px" fontWeight="500" checked={selectData === 'multi'} handleChange={handleChange} />
						<RegistGroup>
							<InputItem>
								<UserBlockUploadBtn
									disabled={selectMulti}
									setResultData={setResultData}
									resultData={resultData}
									guidList={guidList}
									setGuidList={setGuidList}
									typeError={typeError}
									setTypeError={setTypeError}
								/>
							</InputItem>
							<InputRow>
								<InputItem>
									<Label>제재 방식</Label>
									<SelectInput value={resultData.type} onChange={e => setResultData({ ...resultData, type: e.target.value })} disabled={selectMulti}>
										{blockType.map((data, index) => (
											<option key={index} value={data.value}>
												{selectData === 'multi' ? data.name : '선택'}
											</option>
										))}
									</SelectInput>
								</InputItem>
								<InputItem>
									<Label>제재 기간</Label>
									<SelectInput value={resultData.period} onChange={e => setTimeValue(e)} disabled={selectMulti}>
										{blockPeriod.map((data, index) => (
											<option key={index} value={data.value}>
												{selectData === 'multi' ? data.name : '선택'}
											</option>
										))}
									</SelectInput>
								</InputItem>
								<InputItem>
									<Label>제재 사유</Label>
									<SelectInput value={resultData.sanctions} onChange={e => setResultData({ ...resultData, sanctions: e.target.value })} disabled={selectMulti}>
										{blockSanctions.map((data, index) => (
											<option key={index} value={data.value}>
												{selectData === 'multi' ? data.name : '선택'}
											</option>
										))}
									</SelectInput>
								</InputItem>
							</InputRow>
							<InputRow>
								<InputItem>
									<Label>시작 일시</Label>
									<InputGroup>
										<DatePickerWrapper>
											<DatePickerComponent
												name="시작 일자"
												handleSelectedDate={data => handleSelectedDate(data)}
												selectedDate={resultData.start_dt}
												disabled={selectMulti || !resultData.period}
												pastDate={new Date()}
											/>
										</DatePickerWrapper>
										<SelectInput onChange={e => handleSendTime(e)} id="hour" disabled={selectMulti || !resultData.period} value={sendHour}>
											{HourList.map(hour => (
												<option value={hour} key={hour}>
													{hour}
												</option>
											))}
										</SelectInput>
										<SelectInput onChange={e => handleSendTime(e)} id="min" disabled={selectMulti || !resultData.period} value={sendMin}>
											{MinuteList.map(min => (
												<option value={min} key={min}>
													{min}
												</option>
											))}
										</SelectInput>
									</InputGroup>
								</InputItem>

								<InputItem>
									<Label>만료 일시</Label>
									<InputGroup>
										<DatePickerWrapper>
											<DatePicker
												disabled
												selected={selectData === 'multi' ? resultData.end_dt : ''}
												onChange={date => setStartDate(date)}
												className="datepicker"
												placeholderText="만료일자"
												calendarClassName="calendar"
												dateFormat="yyyy - MM - dd"
												locale="ko"
												renderCustomHeader={({ date, changeYear, changeMonth, decreaseMonth, increaseMonth, prevMonthButtonDisabled, nextMonthButtonDisabled }) => (
													<div className="calendar-top">
														<button
															className="btn-prev"
															onClick={e => {
																e.preventDefault();
																decreaseMonth();
															}}
															disabled={prevMonthButtonDisabled}></button>
														<select value={getYear(date)} onChange={({ target: { value } }) => changeYear(value)}>
															{years.map(option => (
																<option key={option} value={option}>
																	{option}
																</option>
															))}
														</select>
														.
														<select value={months[getMonth(date)]} onChange={({ target: { value } }) => changeMonth(months.indexOf(value))}>
															{months.map(option => (
																<option key={option} value={option}>
																	{option}
																</option>
															))}
														</select>
														<button
															className="btn-next"
															onClick={e => {
																e.preventDefault();
																increaseMonth();
															}}
															disabled={nextMonthButtonDisabled}></button>
													</div>
												)}
											/>
										</DatePickerWrapper>
										<SelectInput disabled>
											<option value="">{selectData === 'multi' ? endHour : '00'}</option>
										</SelectInput>
										<SelectInput disabled>
											<option value="">{selectData === 'multi' ? sendMin : '00'}</option>
										</SelectInput>
									</InputGroup>
								</InputItem>
							</InputRow>
						</RegistGroup>
					</div>

					{isNullValue && <SearchBarAlert>설정값을 모두 입력해주세요.</SearchBarAlert>}
					<BtnWrapper $justify="flex-end" $gap="10px">
						<Button
							text="취소"
							theme="line"
							handleClick={e => {
								e.preventDefault();
								navigate('/servicemanage/userblock');
							}}
						/>
						<Button type="submit" text="등록" name="등록버튼" handleClick={handleRegistModalClose} theme={notNull ? 'primary' : 'disable'} />
					</BtnWrapper>

					{/* 일괄등록 모달창 */}
					<Modal min="440px" $padding="40px" $bgcolor="transparent" $view={registModalClose}>
						<BtnWrapper $justify="flex-end">
							<ButtonClose onClick={handleRegistModalClose} />
						</BtnWrapper>
						<ModalText $align="center">
							이용자 제재 명단에
							<br />
							등록하시겠습니까?
						</ModalText>
						<BtnWrapper $gap="10px">
							<Button text="취소" theme="line" size="large" width="100%" handleClick={handleRegistModalClose} />
							<Button text="확인" theme="primary" type="submit" size="large" width="100%" handleClick={handleRegist} />
						</BtnWrapper>
					</Modal>

					{/* 등록 완료 모달 */}
					<Modal min="440px" $padding="40px" $bgcolor="transparent" $view={completeModalClose}>
						<BtnWrapper $justify="flex-end">
							<ButtonClose onClick={handleCompleteModalClose} />
						</BtnWrapper>
						<ModalText $align="center">{confirmText}</ModalText>
						<BtnWrapper $gap="10px">
							<Button text="확인" theme="primary" type="submit" size="large" width="100%" handleClick={handleCompleteModalClose} />
						</BtnWrapper>
					</Modal>
				</>
			)}
		</>
	);
};

export default UserBlockRegist;

const RegistGroup = styled.div`
	display: flex;
	width: 100%;
	flex-flow: column;
	gap: 20px;
	padding: 20px 0;
	border-top: 1px solid #000;
	border-bottom: 1px solid #000;
	font-size: 14px;
	margin-bottom: 40px;
`;

const InputRow = styled.div`
	display: flex;
	flex-wrap: wrap;
	gap: 20px 50px;
`;

const InputItem = styled.div`
	display: inline-flex;
	align-items: center;
	${TextInput},${SelectInput} {
		height: 35px;
		font-size: 14px;
	}
`;

const Label = styled.div`
	display: block;
	min-width: 120px;
	text-align: center;
`;

const InputGroup = styled.div`
	display: flex;
	gap: 5px;
	button {
		height: 35px;
	}
`;

const TableWrapper = styled.div`
	margin-top: 5px;
	margin-bottom: 30px;
	max-height: 324px;
	overflow: auto;
	&::-webkit-scrollbar {
		width: 4px;
	}
	&::-webkit-scrollbar-thumb {
		background: #666666;
	}
	&::-webkit-scrollbar-track {
		background: #d9d9d9;
	}
`;
const Count = styled.div`
	font-size: 14px;
`;

const FileInput = styled(TextInput)`
	height: 35px;
	border: 1px solid #e0e0e0;
	border-radius: 5px;
	width: 300px;
	padding: 0 15px;
	line-height: 35px;
	font-size: 14px;
	cursor: pointer;
	&::file-selector-button {
		display: none;
	}
`;

const SearchBarAlert = styled.div`
	display: ${props => (props.$view === 'hidden' ? 'none' : 'flex')};
	justify-content: right;
	width: 100%;
	padding-bottom: 20px;
	color: #d60000;
`;
