'use client';

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

import Link from 'next/link';
import { Icon } from '@iconify/react';
import Button from '@/components/Button';
import { useModal } from '@/components/Modal';
import ConfirmationModal from '@/components/modal/ConfirmationModal';
import ConfirmationModalWithNotes from '@/components/modal/ConfirmationModalWithNotes';
import RealizationStatusBadge from '@/components/pages/expense/RealizationStatusBadge';
import ExpenseStatusBadge from '@/components/pages/expense/ExpenseStatusBadge';
import DropFileInput from '@/components/input/DropFileInput';

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

interface ExpenseDetailProps {
  initialValues?: Expense;
}

const ExpenseDetail: React.FC<ExpenseDetailProps> = ({ initialValues }) => {
  const router = useRouter();

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

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

  const isLatestApprovalRejectedOrDone =
    initialValues?.approval &&
    (initialValues.approval.action === 'REJECTED' ||
      initialValues.approval.step_number === 5);

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

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

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

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

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

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

    try {
      await ExpenseApi.delete(initialValues?.id as number);

      toast.success('Berhasil menghapus data biaya operasional!');
      router.push('/expense');
    } catch (error) {
      toast.error('Gagal menghapus data biaya operasional!');
    } finally {
      deleteModal.closeModal();
      setIsDeleteLoading(false);
    }
  };

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

    const approveResponse = await ExpenseApi.approve(
      initialValues?.id as number,
      notes
    );

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

      toast.success('Berhasil approve pengajuan biaya operasional!');
      router.push('/expense');
    } else {
      approveModal.closeModal();

      toast.error('Gagal approve pengajuan biaya operasional!');
    }

    setIsApproveLoading(false);
  };

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

    const rejectResponse = await ExpenseApi.reject(
      initialValues?.id as number,
      notes
    );

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

      toast.success('Berhasil reject pengajuan biaya operasional!');
      router.push('/expense');
    } else {
      rejectModal.closeModal();

      toast.error('Gagal reject pengajuan biaya operasional!');
    }

    setIsRejectLoading(false);
  };

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

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

    newRequestDocuments?.splice(deletedFileIdx, 1);

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

  return (
    <>
      <section className='w-full max-w-7xl pb-16'>
        <header className='flex flex-col gap-4'>
          <Button
            href='/expense'
            variant='link'
            className='w-fit p-0 text-primary'
          >
            <Icon icon='uil:arrow-left' width={24} height={24} />
            Kembali
          </Button>

          <h1 className='text-2xl font-bold text-center'>
            Detail Biaya Operasional
          </h1>
        </header>

        <div className='w-full mt-4 flex flex-col gap-4'>
          {/* TODO: apply RBAC */}
          {!isLatestApprovalRejectedOrDone && (
            <div className='w-full max-w-3xl mx-auto flex flex-row justify-end gap-2'>
              <Button
                variant='outline'
                color='success'
                onClick={approveClickHandler}
                className='w-full sm:w-fit'
              >
                <Icon icon='material-symbols:check' width={24} height={24} />
                Approve
              </Button>

              <Button
                variant='outline'
                color='error'
                onClick={rejectClickHandler}
                className='w-full sm:w-fit'
              >
                <Icon icon='material-symbols:close' width={24} height={24} />
                Reject
              </Button>

              <Button
                type='button'
                color='warning'
                href={`/expense/detail/edit/?expenseId=${initialValues?.id}`}
                className='px-4 ml-2'
              >
                <Icon icon='mdi:pencil-outline' width={24} height={24} />
                Edit
              </Button>

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

          {/* TODO: add and integrate ApprovalSteps component with API */}

          <div className='overflow-x-auto w-full max-w-3xl mx-auto'>
            <table className='table table-sm table-zebra'>
              <tbody>
                <tr>
                  <th>Nomor PO</th>
                  <th>:</th>
                  <td>{initialValues?.po_number ?? '-'}</td>
                </tr>
                <tr>
                  <th>Nomor Referensi</th>
                  <th>:</th>
                  <td>{initialValues?.reference_number}</td>
                </tr>
                <tr>
                  <th>Lokasi</th>
                  <th>:</th>
                  <td>{initialValues?.location.name}</td>
                </tr>
                <tr>
                  <th>Kandang</th>
                  <th>:</th>
                  <td>
                    {initialValues?.kandangs
                      .map((item) => item.name)
                      .join(', ')}
                  </td>
                </tr>
                <tr>
                  <th>Vendor</th>
                  <th>:</th>
                  <td>{initialValues?.vendor.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?.nominal ?? 0)}</td>
                </tr>
                <tr>
                  <th>Nominal Sudah Bayar</th>
                  <th>:</th>
                  <td>{formatCurrency(initialValues?.paid ?? 0)}</td>
                </tr>
                <tr>
                  <th>Nominal Sisa Bayar</th>
                  <th>:</th>
                  <td>{formatCurrency(initialValues?.remaining_cost ?? 0)}</td>
                </tr>
                <tr>
                  <th>Status Pencairan</th>
                  <th>:</th>
                  <td>
                    <RealizationStatusBadge
                      approval={initialValues?.approval}
                    />
                  </td>
                </tr>
                <tr>
                  <th>Status Biaya</th>
                  <th>:</th>
                  <td>
                    <ExpenseStatusBadge approval={initialValues?.approval} />
                  </td>
                </tr>
                <tr>
                  <th>Dokumen Pengajuan</th>
                  <th>:</th>
                  <td>
                    <div>
                      {initialValues?.request_documents.length === 0 && '-'}

                      {initialValues?.request_documents &&
                        initialValues?.request_documents.length > 0 && (
                          <ul className='list-disc'>
                            {initialValues?.request_documents.map(
                              (requestDocument, requestDocumentIdx) => (
                                <li key={requestDocumentIdx}>
                                  <Link
                                    href={requestDocument.url}
                                    target='_blank'
                                    rel='noopener noreferrer'
                                    className='text-blue-500 underline'
                                  >
                                    {requestDocument.name}{' '}
                                    <Icon
                                      icon='cuida:open-in-new-tab-outline'
                                      width={12}
                                      height={12}
                                      className='inline'
                                    />
                                  </Link>
                                </li>
                              )
                            )}
                          </ul>
                        )}
                    </div>

                    <div className='flex flex-col gap-2'>
                      <DropFileInput
                        name='request_documents'
                        values={formik.values.request_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.request_documents &&
                        formik.values.request_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>
                  </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?.kandang_expenses.map(
              (kandangExpense, kandangExpenseIdx) => {
                let expenseGrandTotal = 0;

                kandangExpense.expenses.forEach(
                  (item) => (expenseGrandTotal += item.total_expense)
                );

                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'
                          >
                            Biaya {kandangExpense.kandang.name}
                          </th>
                        </tr>
                        <tr>
                          <th>Nonstock</th>
                          <th>Total Kuantitas</th>
                          <th>Total Biaya</th>
                          <th>Catatan</th>
                        </tr>
                      </thead>
                      <tbody>
                        {kandangExpense.expenses.map(
                          (expenseItem, expenseIdx) => (
                            <tr key={expenseIdx}>
                              <td>{expenseItem.nonstock.name}</td>
                              <td>{expenseItem.total_quantity}</td>
                              <td>
                                {formatCurrency(expenseItem.total_expense)}
                              </td>
                              <td className='w-xs'>
                                {expenseItem.notes ?? '-'}
                              </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>
      </section>

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

      <ConfirmationModalWithNotes
        ref={approveModal.ref}
        type='success'
        text='Apakah anda yakin ingin approve data transfer ke laying 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 transfer ke laying ini?'
        secondaryButton={{
          text: 'Tidak',
        }}
        primaryButton={{
          text: 'Ya',
          color: 'error',
          isLoading: isRejectLoading,
          onClick: confirmationModalRejectClickHandler,
        }}
      />
    </>
  );
};

export default ExpenseDetail;
