'use client';

import { useEffect, useState } from 'react';
import { useRouter } from 'next/navigation';
import { useFormik } from 'formik';
import useSWR from 'swr';
import toast from 'react-hot-toast';

import { Icon } from '@iconify/react';
import Link from 'next/link';
import Button from '@/components/Button';
import RealizationStatusBadge from '@/components/pages/expense/RealizationStatusBadge';
import ExpenseStatusBadge from '@/components/pages/expense/ExpenseStatusBadge';
import DropFileInput from '@/components/input/DropFileInput';
import ApprovalSteps, {
  useApprovalSteps,
} from '@/components/pages/ApprovalSteps';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
import ExpensePDFPreviewButton from '@/components/pages/expense//pdf/ExpensePDFButton';
import RequirePermission from '@/components/helper/RequirePermission';

import { Expense } from '@/types/api/expense';
import { formatCurrency, formatDate } from '@/lib/helper';
import {
  UploadRequestDocumentsFormSchema,
  UploadRequestDocumentsFormValues,
} from '@/components/pages/expense/form/ExpenseRequestForm.schema';
import { ACCEPTED_FILE_TYPE, S3_PUBLIC_BASE_URL } from '@/config/constant';
import { ExpenseApi } from '@/services/api/expense';
import { isResponseSuccess } from '@/lib/api-helper';
import { EXPENSE_REQUEST_APPROVAL_LINE } from '@/config/approval-line';
import { BaseApiResponse } from '@/types/api/api-general';

interface ExpenseRequestContentProps {
  initialValues?: Expense;
}

const ExpenseRequestContent = ({
  initialValues,
}: ExpenseRequestContentProps) => {
  const router = useRouter();

  const { approvals: approvalHistory, isLoading: isLoadingApprovalHistory } =
    useApprovalSteps({
      latestApproval: initialValues?.latest_approval,
      approvalLines: EXPENSE_REQUEST_APPROVAL_LINE,
      moduleName: 'EXPENSES',
      moduleId: initialValues?.id.toString() ?? '',
      params: {
        page: 1,
        limit: 100,
      },
    });

  const isLatestApprovalRejected =
    initialValues?.latest_approval.action === 'REJECTED';

  const isLatestApprovalRejectedOrDone =
    isLatestApprovalRejected ||
    initialValues?.latest_approval.step_number === 5;

  const isCurrentApprovalOnManager =
    !isLatestApprovalRejected &&
    initialValues?.latest_approval.step_number === 1;

  const isCurrentApprovalOnFinance =
    !isLatestApprovalRejected &&
    initialValues?.latest_approval.step_number === 2;

  const isCurrentApprovalOnRealization =
    !isLatestApprovalRejected &&
    initialValues?.latest_approval.step_number === 4;

  const showEditButton =
    initialValues?.latest_approval.step_number !== 5 &&
    (initialValues?.latest_approval.step_number === 1 ||
      initialValues?.latest_approval.step_number === 2 ||
      initialValues?.latest_approval.step_number === 3);

  const showRejectButton =
    !isLatestApprovalRejected &&
    (initialValues?.latest_approval.step_number === 1 ||
      initialValues?.latest_approval.step_number === 2);

  const isExpenseCanBeRealized =
    !isLatestApprovalRejected &&
    initialValues?.latest_approval.step_number === 3;

  // Modal hooks
  const deleteModal = useModal();
  const completeModal = useModal();
  const approveModal = useModal();
  const rejectModal = useModal();

  // Modal loading state
  const [isDeleteLoading, setIsDeleteLoading] = useState(false);
  const [isCompleteLoading, setIsCompleteLoading] = useState(false);
  const [isApproveLoading, setIsApproveLoading] = useState(false);
  const [isRejectLoading, setIsRejectLoading] = useState(false);

  const formik = useFormik<UploadRequestDocumentsFormValues>({
    initialValues: {
      documents: [],
    },
    validationSchema: UploadRequestDocumentsFormSchema,
    onSubmit: async (values) => {
      const addRequestDocumentsRes = await ExpenseApi.uploadRequestDocuments(
        initialValues?.id as number,
        values.documents
      );

      if (isResponseSuccess(addRequestDocumentsRes)) {
        toast.success(addRequestDocumentsRes.message);
        window.location.reload();
      } else {
        toast.error(String(addRequestDocumentsRes?.message));
      }
    },
  });

  const deleteExpenseClickHandler = () => {
    deleteModal.openModal();
  };

  const completeExpenseClickHandler = () => {
    completeModal.openModal();
  };

  const approveClickHandler = () => {
    approveModal.openModal();
  };

  const rejectClickHandler = () => {
    rejectModal.openModal();
  };

  // Modal confirm click handler
  const confirmationModalDeleteClickHandler = async () => {
    setIsDeleteLoading(true);

    const deleteResponse = await ExpenseApi.delete(initialValues?.id as number);

    if (isResponseSuccess(deleteResponse)) {
      toast.success('Berhasil menghapus data biaya operasional!');
      router.push('/expense');
    } else {
      toast.error('Gagal menghapus data biaya operasional!');
    }

    deleteModal.closeModal();
    setIsDeleteLoading(false);
  };

  const confirmationModalCompleteClickHandler = async () => {
    setIsCompleteLoading(true);

    const completeRes = await ExpenseApi.complete(initialValues?.id as number);

    if (isResponseSuccess(completeRes)) {
      toast.success(completeRes.message);
      router.push('/expense');
    } else {
      toast.error(completeRes?.message as string);
    }

    completeModal.closeModal();
    setIsCompleteLoading(false);
  };

  const confirmationModalApproveClickHandler = async (notes: string) => {
    setIsApproveLoading(true);

    let approveResponse: BaseApiResponse<Expense> | undefined = undefined;

    if (isCurrentApprovalOnManager) {
      approveResponse = await ExpenseApi.approveManager(
        initialValues.id,
        notes
      );
    }

    if (isCurrentApprovalOnFinance) {
      approveResponse = await ExpenseApi.approveFinance(
        initialValues.id,
        notes
      );
    }

    if (isResponseSuccess(approveResponse)) {
      approveModal.closeModal();

      toast.success(approveResponse?.message);
      router.push('/expense');
    } else {
      approveModal.closeModal();

      toast.error(approveResponse?.message as string);
    }

    setIsApproveLoading(false);
  };

  const confirmationModalRejectClickHandler = async (notes: string) => {
    setIsRejectLoading(true);

    let rejectResponse: BaseApiResponse<Expense> | undefined = undefined;

    if (isCurrentApprovalOnManager) {
      rejectResponse = await ExpenseApi.rejectManager(initialValues.id, notes);
    }

    if (isCurrentApprovalOnFinance) {
      rejectResponse = await ExpenseApi.rejectFinance(initialValues.id, notes);
    }

    if (isResponseSuccess(rejectResponse)) {
      rejectModal.closeModal();

      toast.success(rejectResponse.message);
      router.push('/expense');
    } else {
      rejectModal.closeModal();

      toast.error(rejectResponse?.message as string);
    }

    setIsRejectLoading(false);
  };

  const requestDocumentsChangeHandler = (val: File[]) => {
    formik.setFieldTouched('documents', true);
    formik.setFieldValue('documents', val);
  };

  const requestDocumentsDeleteHandler = (deletedFileIdx: number) => {
    const newRequestDocuments = formik.values.documents;

    newRequestDocuments?.splice(deletedFileIdx, 1);

    formik.setFieldValue('documents', newRequestDocuments);
  };

  return (
    <>
      <div>
        {initialValues && !isLoadingApprovalHistory && approvalHistory && (
          <div className='w-full max-w-5xl my-4 mx-auto'>
            <ApprovalSteps approvals={approvalHistory} />
          </div>
        )}

        <div className='w-full mt-4 flex flex-col gap-4'>
          {/* TODO: apply RBAC */}

          <div className='w-full max-w-5xl mx-auto flex flex-col sm:flex-row justify-end gap-2'>
            {isCurrentApprovalOnManager && (
              <RequirePermission permissions='lti.expense.approve.manager'>
                <Button
                  variant='outline'
                  color='info'
                  onClick={approveClickHandler}
                  className='w-full sm:w-fit'
                >
                  <Icon icon='lucide-lab:farm' width={24} height={24} />
                  Approve Manager
                </Button>
              </RequirePermission>
            )}

            {isCurrentApprovalOnFinance && (
              <RequirePermission permissions='lti.expense.approve.finance'>
                <Button
                  variant='outline'
                  color='success'
                  onClick={approveClickHandler}
                  className='w-full sm:w-fit'
                >
                  <Icon icon='tdesign:money' width={24} height={24} />
                  Approve Finance
                </Button>
              </RequirePermission>
            )}

            {isCurrentApprovalOnRealization && (
              <RequirePermission permissions='lti.expense.complete.expense'>
                <Button
                  variant='outline'
                  color='success'
                  onClick={completeExpenseClickHandler}
                  className='w-full sm:w-fit'
                >
                  <Icon
                    icon='material-symbols:done-all-rounded'
                    width={24}
                    height={24}
                  />
                  Selesai
                </Button>
              </RequirePermission>
            )}

            {showRejectButton && (
              <RequirePermission
                permissions={[
                  'lti.expense.approve.manager',
                  'lti.expense.approve.finance',
                ]}
              >
                <Button
                  variant='outline'
                  color='error'
                  onClick={rejectClickHandler}
                  className='w-full:w-fit'
                >
                  <Icon icon='material-symbols:close' width={24} height={24} />
                  Reject
                </Button>
              </RequirePermission>
            )}

            {isExpenseCanBeRealized && (
              <RequirePermission permissions='lti.expense.create.realization'>
                <Button
                  variant='outline'
                  color='info'
                  href={`/expense/realization/?expenseId=${initialValues?.id}`}
                  className='w-full sm:w-fit'
                >
                  <Icon
                    icon='material-symbols:money-bag-rounded'
                    width={24}
                    height={24}
                  />
                  Realisasi
                </Button>
              </RequirePermission>
            )}

            <div className='w-full sm:w-fit sm:ml-2 flex flex-row gap-2 items-center'>
              {showEditButton && (
                <RequirePermission permissions='lti.expense.update'>
                  <Button
                    type='button'
                    color='warning'
                    href={`/expense/detail/edit/?expenseId=${initialValues?.id}`}
                    className='px-4 grow sm:grow-0'
                  >
                    <Icon icon='mdi:pencil-outline' width={24} height={24} />
                    Edit
                  </Button>
                </RequirePermission>
              )}

              <RequirePermission permissions='lti.expense.delete'>
                <Button
                  type='button'
                  color='error'
                  onClick={deleteExpenseClickHandler}
                  className='px-4 grow sm:grow-0'
                >
                  <Icon
                    icon='material-symbols:delete-outline-rounded'
                    width={24}
                    height={24}
                    className='justify-start text-sm'
                  />
                  Delete
                </Button>
              </RequirePermission>
            </div>
          </div>

          <div className='overflow-x-auto w-full max-w-5xl mx-auto'>
            <table className='table table-sm table-zebra'>
              <tbody>
                <tr>
                  <th>Nomor PO</th>
                  <th>:</th>
                  <td>
                    {!initialValues?.po_number && '-'}
                    {initialValues?.po_number && (
                      <ExpensePDFPreviewButton expense={initialValues} />
                    )}
                  </td>
                </tr>
                <tr>
                  <th>Nomor Referensi</th>
                  <th>:</th>
                  <td>{initialValues?.reference_number}</td>
                </tr>
                <tr>
                  <th>Kategori</th>
                  <th>:</th>
                  <td>
                    {initialValues?.category === 'BOP'
                      ? 'Biaya Operasional'
                      : 'Non Biaya Operasional'}
                  </td>
                </tr>
                <tr>
                  <th>Lokasi</th>
                  <th>:</th>
                  <td>{initialValues?.location.name}</td>
                </tr>
                <tr>
                  <th>Kandang</th>
                  <th>:</th>
                  <td>
                    {initialValues?.kandangs &&
                    initialValues?.kandangs.some((k) => k.name)
                      ? initialValues?.kandangs
                          .filter((item) => item.name)
                          .map((item) => item.name)
                          .join(', ')
                      : '-'}
                  </td>
                </tr>
                <tr>
                  <th>Vendor</th>
                  <th>:</th>
                  <td>{initialValues?.supplier.name}</td>
                </tr>
                <tr>
                  <th>Tanggal Transaksi</th>
                  <th>:</th>
                  <td>
                    {formatDate(
                      initialValues?.transaction_date,
                      'DD MMMM YYYY'
                    )}
                  </td>
                </tr>
                <tr>
                  <th>Tanggal Realisasi</th>
                  <th>:</th>
                  <td>
                    {initialValues?.realization_date
                      ? formatDate(
                          initialValues?.realization_date,
                          'DD MMMM YYYY'
                        )
                      : '-'}
                  </td>
                </tr>
                <tr>
                  <th>Nama Pengaju</th>
                  <th>:</th>
                  <td>{initialValues?.created_user.name}</td>
                </tr>
                <tr>
                  <th>Nominal Biaya</th>
                  <th>:</th>
                  <td>
                    {formatCurrency(
                      initialValues?.latest_approval.step_number === 4 ||
                        initialValues?.latest_approval.step_number === 5
                        ? (initialValues?.total_realisasi ?? 0)
                        : (initialValues?.total_pengajuan ?? 0)
                    )}
                  </td>
                </tr>
                <tr>
                  <th>Status Pencairan</th>
                  <th>:</th>
                  <td>
                    <RealizationStatusBadge
                      approval={initialValues?.latest_approval}
                    />
                  </td>
                </tr>
                <tr>
                  <th>Status Biaya</th>
                  <th>:</th>
                  <td>
                    <ExpenseStatusBadge
                      approval={initialValues?.latest_approval}
                    />
                  </td>
                </tr>
                <tr>
                  <th>Dokumen Pengajuan</th>
                  <th>:</th>
                  <td>
                    <div>
                      {!initialValues?.documents ||
                        (initialValues?.documents &&
                          initialValues?.documents.length === 0 &&
                          '-')}

                      {initialValues?.documents &&
                        initialValues?.documents.length > 0 && (
                          <ul className='list-disc'>
                            {initialValues?.documents.map(
                              (requestDocument, requestDocumentIdx) => {
                                const path = requestDocument.path.startsWith(
                                  '/'
                                )
                                  ? requestDocument.path.slice(1)
                                  : requestDocument.path;
                                const documentUrl = `${S3_PUBLIC_BASE_URL}/${path}`;
                                return (
                                  <li key={requestDocumentIdx}>
                                    <Link
                                      href={documentUrl}
                                      target='_blank'
                                      rel='noopener noreferrer'
                                      className='text-blue-500 underline'
                                    >
                                      {requestDocument.path}{' '}
                                      <Icon
                                        icon='cuida:open-in-new-tab-outline'
                                        width={12}
                                        height={12}
                                        className='inline'
                                      />
                                    </Link>
                                  </li>
                                );
                              }
                            )}
                          </ul>
                        )}
                    </div>

                    <RequirePermission permissions='lti.expense.document'>
                      <div className='flex flex-col gap-2'>
                        <DropFileInput
                          name='documents'
                          values={formik.values.documents}
                          onChange={requestDocumentsChangeHandler}
                          onDelete={requestDocumentsDeleteHandler}
                          accept={{
                            ...ACCEPTED_FILE_TYPE.PDF,
                            ...ACCEPTED_FILE_TYPE.IMAGE,
                          }}
                          maxFiles={10}
                          className={{
                            wrapper: 'mt-2',
                            inputWrapper: 'flex items-center',
                          }}
                        />

                        {formik.values.documents &&
                          formik.values.documents.length > 0 && (
                            <Button
                              onClick={formik.submitForm}
                              disabled={formik.isSubmitting}
                              isLoading={formik.isSubmitting}
                              className='w-fit self-end'
                            >
                              <Icon
                                icon='ic:round-plus'
                                width={24}
                                height={24}
                              />
                              Tambah
                            </Button>
                          )}
                      </div>
                    </RequirePermission>
                  </td>
                </tr>
              </tbody>
            </table>
          </div>
        </div>
        <div className='w-full max-w-5xl mt-8 mx-auto'>
          <h2 className='font-bold text-xl text-center'>
            Rincian Pengajuan Biaya Operasional
          </h2>

          <div className='w-full mt-2 flex flex-col gap-4'>
            {initialValues?.kandangs.map(
              (kandangExpense, kandangExpenseIdx) => {
                let expenseGrandTotal = 0;

                kandangExpense.pengajuans?.forEach(
                  (item) => (expenseGrandTotal += item.qty * item.price)
                );

                return (
                  <div
                    key={kandangExpenseIdx}
                    className='overflow-x-auto w-full mx-auto'
                  >
                    <table className='table table-sm table-zebra'>
                      <thead>
                        <tr>
                          <th
                            colSpan={5}
                            className='font-bold text-center text-base-content text-lg'
                          >
                            {kandangExpense.kandang_id && kandangExpense.name
                              ? `Biaya ${kandangExpense.name}`
                              : `Biaya ${initialValues?.location.name || 'Umum'}`}
                          </th>
                        </tr>
                        <tr>
                          <th>Nonstock</th>
                          <th>Total Kuantitas</th>
                          <th>Harga Satuan</th>
                          <th>Catatan</th>
                        </tr>
                      </thead>
                      <tbody>
                        {kandangExpense.pengajuans?.map(
                          (pengajuanItem, pengajuanIdx) => (
                            <tr key={pengajuanIdx}>
                              <td>{pengajuanItem.nonstock.name}</td>
                              <td>{pengajuanItem.qty}</td>
                              <td>{formatCurrency(pengajuanItem.price)}</td>
                              <td className='w-xs'>
                                {pengajuanItem.note ?? '-'}
                              </td>
                            </tr>
                          )
                        )}
                      </tbody>
                      <tfoot>
                        <tr className='border-y'>
                          <th colSpan={2} className='text-right'>
                            Total Biaya Keseluruhan:
                          </th>
                          <th colSpan={2}>
                            {formatCurrency(expenseGrandTotal)}
                          </th>
                        </tr>
                      </tfoot>
                    </table>
                  </div>
                );
              }
            )}
          </div>
        </div>
      </div>

      <ConfirmationModal
        ref={deleteModal.ref}
        type='error'
        text='Apakah anda yakin ingin menghapus data biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isDeleteLoading,
          onClick: confirmationModalDeleteClickHandler,
        }}
      />

      <ConfirmationModal
        ref={completeModal.ref}
        type='success'
        text='Apakah anda yakin ingin menyelesaikan biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'success',
          isLoading: isCompleteLoading,
          onClick: confirmationModalCompleteClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={approveModal.ref}
        type='success'
        text='Apakah anda yakin ingin approve data biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'success',
          isLoading: isApproveLoading,
          onClick: confirmationModalApproveClickHandler,
        }}
      />

      <ConfirmationModalWithNotes
        ref={rejectModal.ref}
        type='error'
        text='Apakah anda yakin ingin reject data biaya operasional ini?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isRejectLoading,
          onClick: confirmationModalRejectClickHandler,
        }}
      />
    </>
  );
};

export default ExpenseRequestContent;
