import { useMemo } from 'react';

import { Series, SeriesResource, Type } from '@/back-api';
import { useServiceContext } from '@/service/ServiceContext';
import { SessionServiceProps } from '@/service/session';
import { DataStoreType, useDataStore } from '@/utils/data-store';
import { DataTools, TypeCheck } from '@/utils/data-tools';
import { isNullOrUndefined } from '@/utils/validator';

import { useMediaService } from './Media';
import { useSeasonService } from './Season';

export type SeriesServiceProps = {
  store: DataStoreType<Series>;
};

export const useSeriesService = (): SeriesServiceProps => {
  const { series } = useServiceContext();
  return series;
};

export const useSeriesServiceWrapped = (
  session: SessionServiceProps
): SeriesServiceProps => {
  const store = useDataStore<Series>(
    {
      restApiName: 'Series',
      primaryKey: 'id',
      available: session.token !== undefined,
      getsCall: () => {
        return SeriesResource.gets({
          restConfig: session.getRestConfig(),
        });
      },
    },
    [session.token]
  );

  return { store };
};

export const useOrderedSeries = (nameFilter?: string) => {
  const { store } = useSeriesService();
  const dataSeries = useMemo(() => {
    let tmpData = store.data;
    if (!isNullOrUndefined(nameFilter)) {
      tmpData = DataTools.getNameLike(tmpData, nameFilter);
    }
    return DataTools.getsWhere(
      tmpData,
      [
        {
          check: TypeCheck.NOT_EQUAL,
          key: 'id',
          value: [undefined, null],
        },
      ],
      ['name', 'id']
    );
  }, [store.data, nameFilter]);
  return { isLoading: store.isLoading, dataSeries };
};
export const useOrderedSeriesWithType = (typeId?: Type["id"], nameFilter?: string) => {
  const { store } = useSeriesService();
  const dataSeries = useMemo(() => {
    let tmpData = store.data;
    if (!isNullOrUndefined(nameFilter)) {
      tmpData = DataTools.getNameLike(tmpData, nameFilter);
    }
    if (typeId === undefined) {
      return [];
    }
    return DataTools.getsWhere(
      tmpData,
      [
        {
          check: TypeCheck.NOT_EQUAL,
          key: 'id',
          value: [undefined, null],
        },
        {
          check: TypeCheck.EQUAL,
          key: 'parentId',
          value: typeId,
        },
      ],
      ['name', 'id']
    );
  }, [store.data, nameFilter, typeId]);
  return { isLoading: store.isLoading, dataSeries };
};

export const useSpecificSeries = (id: number | undefined) => {
  const { store } = useSeriesService();
  const dataSeries = useMemo(() => {
    return store.get(id);
  }, [store.data, id]);
  return { dataSeries };
};

export const useSeriesVideo = (id: number) => {
  const { store } = useSeriesService();
  const seriesVideo = useMemo(() => {
    return DataTools.getsWhere(
      store.data,
      [
        {
          check: TypeCheck.EQUAL,
          key: 'seriesId',
          value: id,
        },
        {
          check: TypeCheck.EQUAL,
          key: 'seasonId',
          value: undefined,
        },
      ],
      ['episode', 'name']
    );
  }, [store.data, id]);
  return { isLoading: store.isLoading, dataTypes: seriesVideo };
};

export const useSeriesCountVideo = (id?: number) => {
  const { store } = useMediaService();
  const seriesCountVideo = useMemo(() => {
    if (id === undefined) {
      return 0;
    }
    return DataTools.count(store.data, [
      {
        check: TypeCheck.EQUAL,
        key: 'seriesId',
        value: id,
      },
    ]);
  }, [store.data, id]);
  return { isLoading: store.isLoading, seriesCountVideo };
};
export const useSeasonWithSeries = (seriesId?: number) => {
  const { store } = useSeasonService();
  const seasonOfSeriesId = useMemo(() => {
    if (seriesId === undefined) {
      return [];
    }
    return DataTools.getsWhere(
      store.data,
      [
        {
          check: TypeCheck.EQUAL,
          key: 'parentId',
          value: seriesId,
        },
      ],
      ['name', 'id']
      // TODO: ['>name', 'id'] padding right request ...:
      // const maxLength = Math.max(...values.map(v => v.length));
      // const paddedA = a.padStart(maxLength, " ");
      // const paddedB = b.padStart(maxLength, " ");
      // return paddedA.localeCompare(paddedB);
    );
  }, [store.data, seriesId]);
  return { isLoading: store.isLoading, seasonOfSeriesId };
};

export const useSeriesWithType = (typeId?: number) => {
  const { store } = useSeriesService();
  const seriesWithType = useMemo(() => {
    if (typeId === undefined) {
      return [];
    }
    return DataTools.getsWhere(
      store.data,
      [
        {
          check: TypeCheck.EQUAL,
          key: 'parentId',
          value: typeId,
        },
      ],
      ['name']
    );
  }, [store.data, typeId]);
  return { isLoading: store.isLoading, seriesWithType };
};
