import moment from 'moment';
import { useStore } from '@/shared/model/store';
import { ChangeEvent, useEffect, useState } from 'react';
import { NumericFormat } from 'react-number-format';
import { IMAGE_ROOT } from '@/shared/constants/common';
import { PATHS } from '@/shared/constants/paths';
import { useNavigate } from '@/shared/lib/hooks/use-navigate';
import { AllTransactionList } from '@/entities/transaction/ui/all-transaction-list';
import { 
  TransactionCategory, 
  AllTransactionSearchCl, 
  AllTransactionListParams, 
  ListItemProps, 
  AllTransactionListSummaryParams, 
  AllTransactionListResponse, 
  AllTransactionListSummaryResponse 
} from '@/entities/transaction/model/types';
import { useAllTransactionListMutation } from '@/entities/transaction/api/use-all-transaction-list-mutation';
import { useAllTransactionListSummaryMutation } from '@/entities/transaction/api/use-all-transaction-list-summary-mutation';
import { useDownloadExcelMutation } from '@/entities/transaction/api/use-download-excel-mutation';
import { DEFAULT_PAGE_PARAM } from '@/entities/common/model/constant';
import { AllTransactionFilter } from '@/entities/transaction/ui/filter/all-transaction-filter';
import { SortTypeBox } from '@/entities/common/ui/sort-type-box';
import { SortTypeKeys, HeaderType, DefaultRequestPagination } from '@/entities/common/model/types';
import {
	useSetOnBack,
	useSetHeaderTitle,
	useSetHeaderType,
	useSetFooterMode
} from '@/widgets/sub-layout/use-sub-layout';
import { EmailBottomSheet } from '@/entities/common/ui/email-bottom-sheet';
import useIntersectionObserver from '@/widgets/intersection-observer';
import { useTranslation } from 'react-i18next';

export const AllTransactionListPage = () => {
  const { navigate } = useNavigate();
  const { t, i18n } = useTranslation();
  const userMid = useStore.getState().UserStore.mid;

  const [serviceCodeOptions, setServiceCodeOptions] = useState<Array<Record<string, any>>>();
  
  const [onActionIntersect, setOnActionIntersect] = useState<boolean>(false);
  const [sortType, setSortType] = useState<SortTypeKeys>(SortTypeKeys.LATEST);
  const [listItems, setListItems] = useState<Array<ListItemProps>>([]);
  const [filterOn, setFilterOn] = useState<boolean>(false);
  const [pageParam, setPageParam] = useState<DefaultRequestPagination>(DEFAULT_PAGE_PARAM);
  const [mid, setMid] = useState<string>(userMid);
  const [moid, setMoid] = useState<string>('');
  const [tid, setTid] = useState<string>('');
  const [dateCl, setDateCl] = useState<string>('');
  const [goodsName, setGoodsName] = useState<string>('');
  // const [fromDate, setFromDate] = useState(moment().subtract(1, 'month').format('YYYYMMDD'));
  const [fromDate, setFromDate] = useState(moment().subtract(2, 'year').format('YYYYMMDD'));
  const [toDate, setToDate] = useState(moment().format('YYYYMMDD'));
  const [statusCode, setStatusCode] = useState<string>('');
  const [serviceCode, setServiceCode] = useState<string>('01');
  const [minAmount, setMinAmount] = useState<number>();
	const [maxAmount, setMaxAmount] = useState<number>();
  const [cardCode, setCardCode] = useState<string | undefined>();
  const [bankCode, setBankCode] = useState<string | undefined>();
  const [searchCl, setSearchCl] = useState<AllTransactionSearchCl | undefined>();
  const [searchValue, setSearchValue] = useState<string | undefined>();

  const [totalCount, setTotalCount] = useState<number>(0);
  const [totalAmount, setTotalAmount] = useState<number>(0);

  const [emailBottomSheetOn, setEmailBottomSheetOn] = useState<boolean>(false);
      
	useSetHeaderTitle(t('transaction.listTitle'));
	useSetHeaderType(HeaderType.LeftArrow);
	useSetOnBack(() => {
		navigate(PATHS.home);
	});
	useSetFooterMode(false);
  
  const { mutateAsync: allTransactionList } = useAllTransactionListMutation();
  const { mutateAsync: allTransactionListSummary } = useAllTransactionListSummaryMutation();
  const { mutateAsync: downloadExcel } = useDownloadExcelMutation();
  const onIntersect: IntersectionObserverCallback = (entries: Array<IntersectionObserverEntry>) => {
    entries.forEach((entry: IntersectionObserverEntry) => {
      if(entry.isIntersecting){
        if(onActionIntersect && !!pageParam.cursor){
          setOnActionIntersect(false);
          callList('page');
        } 
      }
    });
  };

  const { setTarget } = useIntersectionObserver({ 
    threshold: 1, 
    onIntersect 
  });

  const callList = (type?: string) => {
    setOnActionIntersect(false);
    let listSummaryParams: AllTransactionListSummaryParams = {
      mid: mid,
      moid: moid,
      tid: tid,
      fromDate: fromDate,
      toDate: toDate,
      statusCode: statusCode,
      serviceCode: serviceCode,
      minAmount: minAmount,
      maxAmount: maxAmount,
      dateCl: dateCl,
      goodsName: goodsName,
      cardCode: cardCode,
      bankCode: bankCode,
      searchCl: searchCl,
      searchValue: searchValue,
      sortType: sortType
    };
    let listParams: AllTransactionListParams = {
      ...listSummaryParams,
      ...{
        page: {
          ...pageParam,
          ...{ sortType: sortType }
        }
      }
    };
    if(type !== 'page' && listParams.page){
      listParams.page.cursor = null;
    }
    
    allTransactionList(listParams).then((rs: AllTransactionListResponse) => {
      if(type === 'page'){
        setListItems([
          ...listItems,
          ...rs.content
        ]);
      }
      else{
        setListItems(rs.content);
      }
      if(rs.hasNext 
        && rs.nextCursor !== pageParam.cursor
        && rs.content.length === DEFAULT_PAGE_PARAM.size
      ){
        setPageParam({
          ...pageParam,
          ...{ cursor: rs.nextCursor }
        });
      }
      else{
        setPageParam({
          ...pageParam,
          ...{ cursor: null }
        });
      }
      setOnActionIntersect(
        !!rs.hasNext 
        && rs.nextCursor !== pageParam.cursor
        && rs.content.length === DEFAULT_PAGE_PARAM.size
      );
    });
    allTransactionListSummary(listSummaryParams).then((rs: AllTransactionListSummaryResponse) => {
      setTotalAmount(rs.totalAmount);
      setTotalCount(rs.totalCount);
    });
  };
  
  const onClickToOpenFilter = () => {
    setFilterOn(!filterOn);
  };
  const onClickToDownloadExcel = () => {
    setEmailBottomSheetOn(true);
  };
  const onRequestDownloadExcel = (userEmail?: string) => {
    // tid??? 확인 필요
    /*
    downloadExcel({
      // tid: tid
    }).then((rs) => {

    });
    */
  };
  const onClickToSort = (sort: SortTypeKeys) => {
    setSortType(sort);
  };
  const callServiceCodeOptions = () => {
    let serviceCodes = useStore.getState().CommonStore.serviceCodes;
    setServiceCodeOptions(serviceCodes);
    setServiceCode(serviceCodes[0].value);
  };

  const onChangeServiceCode = (e: ChangeEvent<HTMLSelectElement>) => {
    let val = e.target.value;
    // onchagne 에서 useState가 즉시 반영 안되므로 값을 직접 바로 넘긴다.
    setServiceCode(val);
  };

  const getServiceCodeOptions = () => {
    let rs = [];
    if(!!serviceCodeOptions && serviceCodeOptions.length > 0)
    for(let i=0;i<serviceCodeOptions.length;i++){
      const option = serviceCodeOptions[i];
      const localizedName = getLocalizedServiceCodeName(option?.name);
      rs.push(
        <option
          key={`key-${i}`}
          value={option?.value}
        >{ localizedName }</option>
      )
    }
    return rs;
  };

  const getLocalizedServiceCodeName = (name?: string): string => {
    if (!name) return '';

    const nameMap: Record<string, string> = {
      '전체': t('transaction.constants.all'),
      '신용카드': t('transaction.constants.creditCard'),
      '계좌이체': t('transaction.constants.accountTransfer'),
      '가상계좌': t('transaction.constants.virtualAccount'),
      '휴대폰': t('transaction.constants.mobilePayment'),
      '문화상품권': t('transaction.constants.cultureLand'),
      '(구)SSG머니': t('transaction.constants.ssgMoney'),
      'SSG은행계좌결제': t('transaction.constants.ssgBank'),
      '계좌간편결제': t('transaction.constants.accountSimpleTransfer'),
      '티머니페이': t('transaction.constants.tmoneyPay'),
    };

    return nameMap[name] || name;
  };

  useEffect(() => {
    callServiceCodeOptions();
  }, []);

  useEffect(() => {
    callList();
  }, [
    mid, moid, tid, sortType,
    fromDate, toDate, 
    statusCode, serviceCode, 
    minAmount, maxAmount, 
    bankCode, cardCode, 
    searchCl, searchValue
  ]);


	return (
		<>
			<main>
				<div className="tab-content">
					<div className="tab-pane sub active">
						<div className="summary-section">
							<div className="summary-label">{t('transaction.searchAmount')}</div>
							<div className="summary-amount">
								<span className="amount-text">
                  {t('home.money', { value: new Intl.NumberFormat('en-US').format(totalAmount || 0) })}
                </span>
								<div className="summary-actions">
									<button className="filter-btn">
										<img
                      src={ IMAGE_ROOT + '/ico_setting.svg' }
                      alt={t('transaction.searchOptions')}
                      onClick={ () => onClickToOpenFilter() }
                    />
									</button>
									<button className="download-btn">
										<img
                      src={ IMAGE_ROOT + '/ico_download.svg' }
                      alt={t('transaction.download')}
                      onClick={ () => onClickToDownloadExcel() }
                    />
									</button>
								</div>
							</div>
							<div className="summary-details">
								<div className="detail-item">
									<span className="detail-label">{t('transaction.searchDate')}</span>
									<span className="detail-value">{ moment(fromDate).format('YYYY.MM.DD') } ~ { moment(toDate).format('YYYY.MM.DD') }</span>
								</div>
								<div className="detail-item">
									<span className="detail-label">{t('transaction.transactionCount')}</span>
									<span className="detail-value">
                    <NumericFormat
                      value={ totalCount }
                      thousandSeparator
                      displayType="text"
                      prefix={t('transaction.total') + ' '}
                      suffix={' ' + t('home.count')}
                    ></NumericFormat>
                  </span>
								</div>
							</div>
						</div>
							
						<div className="filter-section">
							<SortTypeBox
                sortType={ sortType }
                onClickToSort={ onClickToSort }
              ></SortTypeBox>
							<select 
                value={ serviceCode }
                onChange={ (e) => onChangeServiceCode(e) }>
                { getServiceCodeOptions() }
							</select>
						</div>
            <AllTransactionList 
              listItems={ listItems }
              transactionCategory={ TransactionCategory.AllTransaction }
            ></AllTransactionList>
            <div ref={ setTarget }></div>
					</div>
				</div>
			</main>
      <AllTransactionFilter
        filterOn={ filterOn }
        setFilterOn={ setFilterOn }
        mid={ mid }
        fromDate={ fromDate }
        toDate={ toDate }
        statusCode={ statusCode }
        serviceCode={ serviceCode }
        minAmount={ minAmount }
        maxAmount={ maxAmount }
        cardCode={ cardCode }
        bankCode={ bankCode }
        searchCl={ searchCl }
        searchValue={ searchValue }
        setMid={ setMid }
        setMoid={ setMoid }
        setTid={ setTid }
        setFromDate={ setFromDate }
        setToDate={ setToDate }
        setStatusCode={ setStatusCode }
        setServiceCode={ setServiceCode }
        setMinAmount={ setMinAmount }
        setMaxAmount={ setMaxAmount }
        setCardCode={ setCardCode }
        setBankCode={ setBankCode }
        setSearchCl={ setSearchCl }
        setSearchValue={ setSearchValue }
        serviceCodeOptions={ serviceCodeOptions }
      ></AllTransactionFilter>

      { !!emailBottomSheetOn &&
        <EmailBottomSheet
          bottomSheetOn={ emailBottomSheetOn }
          setBottomSheetOn={ setEmailBottomSheetOn }
          imageSave={ false }
          sendEmail={ true }
          sendRequest={ onRequestDownloadExcel }
        ></EmailBottomSheet>
      }
    </>
	);
};