import axios from 'axios';
import { BaseApiService } from '@/services/api/base';
import { BaseApiResponse, GroupedApprovals } from '@/types/api/api-general';

import {
  CreateTransferToLayingPayload,
  TransferToLaying,
  UpdateTransferToLayingPayload,
} from '@/types/api/production/transfer-to-laying';
import { httpClient } from '@/services/http/client';
import { ProjectFlockAvailableQuantity } from '@/types/api/production/project-flock';
import { isResponseSuccess } from '@/lib/api-helper';

export class TransferToLayingService extends BaseApiService<
  TransferToLaying,
  CreateTransferToLayingPayload,
  UpdateTransferToLayingPayload
> {
  constructor(basePath: string = '') {
    super(basePath);
  }

  async approve(
    id: number,
    notes?: string
  ): Promise<BaseApiResponse<TransferToLaying> | undefined> {
    try {
      const approveRes = await httpClient<BaseApiResponse<TransferToLaying>>(
        `${this.basePath}/approvals`,
        {
          method: 'POST',
          body: {
            action: 'APPROVED',
            approvable_ids: [id],
            notes: notes,
          },
        }
      );

      return approveRes;
    } catch (error) {
      if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
        return error.response?.data;
      }

      return undefined;
    }
  }

  async bulkApprove(
    ids: number[],
    notes?: string
  ): Promise<BaseApiResponse<TransferToLaying> | undefined> {
    try {
      const approveRes = await httpClient<BaseApiResponse<TransferToLaying>>(
        `${this.basePath}/approvals`,
        {
          method: 'POST',
          body: {
            action: 'APPROVED',
            approvable_ids: ids,
            notes: notes,
          },
        }
      );

      return approveRes;
    } catch (error) {
      if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
        return error.response?.data;
      }

      return undefined;
    }
  }

  async reject(
    id: number,
    notes?: string
  ): Promise<BaseApiResponse<TransferToLaying> | undefined> {
    try {
      const rejectRes = await httpClient<BaseApiResponse<TransferToLaying>>(
        `${this.basePath}/approvals`,
        {
          method: 'POST',
          body: {
            action: 'REJECTED',
            approvable_ids: [id],
            notes: notes,
          },
        }
      );

      return rejectRes;
    } catch (error) {
      if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
        return error.response?.data;
      }

      return undefined;
    }
  }

  async bulkReject(
    ids: number[],
    notes?: string
  ): Promise<BaseApiResponse<TransferToLaying> | undefined> {
    try {
      const rejectRes = await httpClient<BaseApiResponse<TransferToLaying>>(
        `${this.basePath}/approvals`,
        {
          method: 'POST',
          body: {
            action: 'REJECTED',
            approvable_ids: ids,
            notes: notes,
          },
        }
      );

      return rejectRes;
    } catch (error) {
      if (axios.isAxiosError<BaseApiResponse<TransferToLaying>>(error)) {
        return error.response?.data;
      }

      return undefined;
    }
  }

  async getAvailabelQty(projectFlockId: number) {
    try {
      const availableQtyRes = await httpClient<
        BaseApiResponse<ProjectFlockAvailableQuantity>
      >(`${this.basePath}/project-flocks/${projectFlockId}/available-qty`);

      return availableQtyRes;
    } catch (error) {
      if (
        axios.isAxiosError<BaseApiResponse<ProjectFlockAvailableQuantity>>(
          error
        )
      ) {
        return error.response?.data;
      }

      return undefined;
    }
  }

  async getMappedFlockKandangsAvailability(projectFlockId: number) {
    try {
      const flockAvailableQty = await this.getAvailabelQty(projectFlockId);

      const flockKandangsAvailableQty = isResponseSuccess(flockAvailableQty)
        ? flockAvailableQty.data.kandangs
        : [];

      const mappedFlockKandangsAvailableQty: Record<
        number,
        (typeof flockKandangsAvailableQty)[0]
      > = {};

      flockKandangsAvailableQty.forEach((item) => {
        if (!mappedFlockKandangsAvailableQty[item.project_flock_kandang_id]) {
          mappedFlockKandangsAvailableQty[item.project_flock_kandang_id] = item;
        }
      });

      return mappedFlockKandangsAvailableQty;
    } catch (error) {
      return undefined;
    }
  }

  async getApprovalHistory(
    transferToLayingId: number,
    group: boolean = true,
    page: number = 1,
    limit: number = 10
  ) {
    try {
      const approvalHistoryRes = await httpClient<GroupedApprovals>(
        '/approvals',
        {
          query: {
            module_name: 'TRANSFER_TO_LAYINGS',
            module_id: transferToLayingId,
            group_step_number: group ? 'true' : 'false',
            page,
            limit,
          },
        }
      );

      return approvalHistoryRes;
    } catch (error) {
      if (axios.isAxiosError<GroupedApprovals>(error)) {
        return error.response?.data;
      }

      return undefined;
    }
  }
}

export const TransferToLayingApi = new TransferToLayingService(
  '/production/transfer_layings'
);
