'use client';

import { ChangeEventHandler, useEffect, useState } from 'react';
import { pdf } from '@react-pdf/renderer';
import toast from 'react-hot-toast';

import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import Dropdown from '@/components/dropdown/Dropdown';
import DateInput from '@/components/input/DateInput';
import SelectInput, {
  OptionType,
  useSelect,
} from '@/components/input/SelectInput';
import Menu from '@/components/menu/Menu';
import MenuItem from '@/components/menu/MenuItem';
import DailyMarketingsTable from '@/components/pages/report/DailyMarketingsTable';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import DailyMarketingReportPDF from '@/components/pages/report/DailyMarketingReportPDF';

import { Area } from '@/types/api/master-data/area';
import {
  AreaApi,
  CustomerApi,
  LocationApi,
  WarehouseApi,
} from '@/services/api/master-data';
import { Warehouse } from '@/types/api/master-data/warehouse';
import { Customer } from '@/types/api/master-data/customer';
import { MarketingReportApi } from '@/services/api/report/marketing-report';
import {
  MARKETING_DATE_FILTER_TYPE_OPTIONS,
  MARKETING_TYPE_OPTIONS,
} from '@/config/constant';
import { httpClient } from '@/services/http/client';
import { BaseApiResponse } from '@/types/api/api-general';
import {
  DailyMarketingReport,
  DailyMarketingReportResponse,
} from '@/types/api/report/marketing';
import { isResponseError } from '@/lib/api-helper';

const DailyMarketingReportContent = () => {
  const {
    state: tableFilterState,
    updateFilter,
    setPage,
    setPageSize,
    toQueryString: getTableFilterQueryString,
    reset: resetFilter,
  } = useTableFilter({
    initial: {
      search: '',
      area_id: '',
      location_id: '',
      warehouse_id: '',
      customer_id: '',
      start_date: '',
      end_date: '',
      marketing_type: '',
      filter_by: '',
      sort_by: '',
    },
    paramMap: {
      page: 'page',
      pageSize: 'limit',
      area_id: 'area_id',
      location_id: 'location_id',
      warehouse_id: 'warehouse_id',
      customer_id: 'customer_id',
      start_date: 'start_date',
      end_date: 'end_date',
      marketing_type: 'marketing_type',
      filter_by: 'filter_by',
      sort_by: 'sort_by',
    },
  });

  const dailyMarketingsReportUrl = `${MarketingReportApi.basePath}${getTableFilterQueryString()}`;

  const [isLoadingExportingToExcel, setIsLoadingExportingToExcel] =
    useState(false);
  const [isLoadingExportingToPdf, setIsLoadingExportingToPdf] = useState(false);

  const [selectedArea, setSelectedArea] = useState<OptionType | null>(null);
  const {
    setInputValue: setAreaInputValue,
    options: areaOptions,
    isLoadingOptions: isLoadingAreaOptions,
    loadMore: loadMoreAreas,
  } = useSelect<Area>(AreaApi.basePath, 'id', 'name');

  const areaChangeHandler = (val: OptionType | OptionType[] | null) => {
    setSelectedArea(val as OptionType);
    updateFilter('area_id', val ? ((val as OptionType).value as string) : '');
  };

  const [selectedLocation, setSelectedLocation] = useState<OptionType | null>(
    null
  );
  const {
    setInputValue: setLocationInputValue,
    options: locationOptions,
    isLoadingOptions: isLoadingLocationOptions,
    loadMore: loadMoreLocations,
  } = useSelect<Location>(LocationApi.basePath, 'id', 'name');

  const locationChangeHandler = (val: OptionType | OptionType[] | null) => {
    setSelectedLocation(val as OptionType);
    updateFilter(
      'location_id',
      val ? ((val as OptionType).value as string) : ''
    );
  };

  const [selectedWarehouse, setSelectedWarehouse] = useState<OptionType | null>(
    null
  );
  const {
    setInputValue: setWarehouseInputValue,
    options: warehouseOptions,
    isLoadingOptions: isLoadingWarehouseOptions,
    loadMore: loadMoreWarehouses,
  } = useSelect<Warehouse>(WarehouseApi.basePath, 'id', 'name');

  const warehouseChangeHandler = (val: OptionType | OptionType[] | null) => {
    setSelectedWarehouse(val as OptionType);
    updateFilter(
      'warehouse_id',
      val ? ((val as OptionType).value as string) : ''
    );
  };

  const [selectedCustomer, setSelectedCustomer] = useState<OptionType | null>(
    null
  );
  const {
    setInputValue: setCustomerInputValue,
    options: customerOptions,
    isLoadingOptions: isLoadingCustomerOptions,
    loadMore: loadMoreCustomers,
  } = useSelect<Customer>(CustomerApi.basePath, 'id', 'name');

  const customerChangeHandler = (val: OptionType | OptionType[] | null) => {
    setSelectedCustomer(val as OptionType);
    updateFilter(
      'customer_id',
      val ? ((val as OptionType).value as string) : ''
    );
  };

  const startDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    updateFilter('start_date', e.target.value ? e.target.value : '');
  };

  const endDateChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    updateFilter('end_date', e.target.value ? e.target.value : '');
  };

  const [selectedMarketingDateFilterType, setSelectedMarketingDateFilterType] =
    useState<OptionType | null>(null);
  const marketingDateFilterTypeChangeHandler = (
    val: OptionType | OptionType[] | null
  ) => {
    setSelectedMarketingDateFilterType(val as OptionType);
    updateFilter('filter_by', val ? ((val as OptionType).value as string) : '');
  };

  const [selectedMarketingType, setSelectedMarketingType] =
    useState<OptionType | null>(null);
  const marketingTypeChangeHandler = (
    val: OptionType | OptionType[] | null
  ) => {
    setSelectedMarketingType(val as OptionType);
    updateFilter(
      'marketing_type',
      val ? ((val as OptionType).value as string) : ''
    );
  };

  const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
    updateFilter('search', e.target.value);
  };

  const filterByChangeHandler = (filterBy: string) => {
    updateFilter('filter_by', filterBy);
  };

  const sortByChangeHandler = (sort: 'asc' | 'desc' | '') => {
    updateFilter('sort_by', sort);
  };

  const exportToExcelHandler = async () => {
    setIsLoadingExportingToExcel(true);

    await MarketingReportApi.exportDailyMarketingToExcel(
      getTableFilterQueryString()
    );

    setIsLoadingExportingToExcel(false);
  };

  const exportToPdfHandler = async () => {
    setIsLoadingExportingToPdf(true);

    const params = new URLSearchParams(getTableFilterQueryString());

    params.set('limit', '9999999');

    const queryString = `?${params.toString()}`;

    try {
      const dailyMarketingsReport =
        await httpClient<DailyMarketingReportResponse>(
          `${MarketingReportApi.basePath}${queryString}`
        );

      if (isResponseError(dailyMarketingsReport)) {
        toast.error('Gagal melakukan export penjualan harian! Coba lagi.');
        return;
      }

      const openPdf = async () => {
        const dailyMarketingReportPdfBlob = await pdf(
          <DailyMarketingReportPDF
            data={dailyMarketingsReport.data}
            total={dailyMarketingsReport.total}
          />
        ).toBlob();

        const dailyMarketingReportPdfUrl = URL.createObjectURL(
          dailyMarketingReportPdfBlob
        );
        window.open(dailyMarketingReportPdfUrl, '_blank');
      };

      const downloadPdf = async () => {
        const blob = await pdf(
          <DailyMarketingReportPDF
            data={dailyMarketingsReport.data}
            total={dailyMarketingsReport.total}
          />
        ).toBlob();
        const url = URL.createObjectURL(blob);

        const link = document.createElement('a');
        link.href = url;
        link.download = 'laporan-penjualan-harian.pdf';
        link.click();

        URL.revokeObjectURL(url);
      };

      await openPdf();
    } catch (error) {
      toast.error('Gagal melakukan export penjualan harian! Coba lagi.');
    }

    setIsLoadingExportingToPdf(false);
  };

  const handleReset = () => {
    setSelectedArea(null);
    setSelectedLocation(null);
    setSelectedWarehouse(null);
    setSelectedCustomer(null);
    setSelectedMarketingType(null);
    resetFilter();
  };

  useEffect(() => {
    if (
      tableFilterState.filter_by === 'realization_date' ||
      tableFilterState.filter_by === 'so_date'
    ) {
      setSelectedMarketingDateFilterType({
        label:
          tableFilterState.filter_by === 'realization_date'
            ? 'Tanggal Realisasi'
            : 'Tanggal SO',
        value: tableFilterState.filter_by,
      });
    } else {
      setSelectedMarketingDateFilterType(null);
    }
  }, [tableFilterState.filter_by]);

  return (
    <div className='w-full border border-gray-200 p-4'>
      <div>
        <h2 className='text-xl font-bold text-center'>Penjualan Harian</h2>
      </div>

      {/* Filters */}
      <div className='flex flex-col gap-4 mb-6'>
        <div className='grid grid-cols-12 gap-4'>
          <SelectInput
            label='Area'
            placeholder='Pilih Area'
            options={areaOptions}
            isLoading={isLoadingAreaOptions}
            value={selectedArea}
            onChange={areaChangeHandler}
            onInputChange={setAreaInputValue}
            onMenuScrollToBottom={loadMoreAreas}
            isClearable
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <SelectInput
            label='Lokasi'
            placeholder='Pilih Lokasi'
            options={locationOptions}
            isLoading={isLoadingLocationOptions}
            value={selectedLocation}
            onChange={locationChangeHandler}
            onInputChange={setLocationInputValue}
            onMenuScrollToBottom={loadMoreLocations}
            isClearable
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <SelectInput
            label='Gudang'
            placeholder='Pilih Gudang'
            options={warehouseOptions}
            isLoading={isLoadingWarehouseOptions}
            value={selectedWarehouse}
            onChange={warehouseChangeHandler}
            onInputChange={setWarehouseInputValue}
            onMenuScrollToBottom={loadMoreWarehouses}
            isClearable
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <SelectInput
            label='Customer'
            placeholder='Pilih Customer'
            options={customerOptions}
            isLoading={isLoadingCustomerOptions}
            value={selectedCustomer}
            onChange={customerChangeHandler}
            onInputChange={setCustomerInputValue}
            onMenuScrollToBottom={loadMoreCustomers}
            isClearable
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <DateInput
            name='startDate'
            label='Tanggal Awal'
            placeholder='Tanggal Realisasi'
            value={tableFilterState.start_date}
            onChange={startDateChangeHandler}
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <DateInput
            name='endDate'
            label='Tanggal Akhir'
            placeholder='Tanggal Realisasi'
            value={tableFilterState.end_date}
            onChange={endDateChangeHandler}
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />
        </div>

        <div className='grid grid-cols-12 gap-4'>
          <SelectInput
            label='Filter Tanggal'
            placeholder='Pilih Filter Tanggal'
            options={MARKETING_DATE_FILTER_TYPE_OPTIONS}
            value={selectedMarketingDateFilterType}
            onChange={marketingDateFilterTypeChangeHandler}
            isClearable
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <SelectInput
            label='Tipe Marketing'
            placeholder='Pilih Tipe Marketing'
            options={MARKETING_TYPE_OPTIONS}
            value={selectedMarketingType}
            onChange={marketingTypeChangeHandler}
            isClearable
            className={{
              wrapper: 'col-span-12 sm:col-span-6 lg:col-span-4',
            }}
          />

          <div className='col-span-12 sm:col-span-6 lg:col-span-8 flex flex-wrap sm:justify-end items-end gap-2'>
            <Button
              color='primary'
              // onClick={handleSearch}
              className='flex-1 sm:flex-none'
            >
              <Icon icon='heroicons:magnifying-glass' width={20} height={20} />
              Cari
            </Button>

            <Button
              color='warning'
              onClick={handleReset}
              className='flex-1 sm:flex-none'
            >
              <Icon icon='heroicons-outline:refresh' width={20} height={20} />
              Reset
            </Button>

            <Dropdown
              align='end'
              direction='bottom'
              trigger={
                <Button>
                  Export{' '}
                  <Icon
                    icon='heroicons-outline:download'
                    width={20}
                    height={20}
                  />
                </Button>
              }
            >
              <Menu>
                <MenuItem
                  title='Export to Excel'
                  icon='icon-park-outline:excel'
                  isLoading={isLoadingExportingToExcel}
                  onClick={exportToExcelHandler}
                  className='text-nowrap'
                />
                <MenuItem
                  title='Export to PDF'
                  icon='icon-park-outline:file-pdf-one'
                  onClick={exportToPdfHandler}
                  className='text-nowrap'
                />
              </Menu>
            </Dropdown>
          </div>
        </div>
      </div>

      <DailyMarketingsTable
        dailyMarketingsReportUrl={dailyMarketingsReportUrl}
        onSetPage={setPage}
        pageSize={tableFilterState.pageSize}
        onSetPageSize={setPageSize}
        searchValue={tableFilterState.search}
        onSearchChange={searchChangeHandler}
        onFilterByChange={filterByChangeHandler}
        onSortByChange={sortByChangeHandler}
      />
    </div>
  );
};

export default DailyMarketingReportContent;
