import { Icon } from '@iconify/react';
import Steps from '@/components/steps/Steps';
import StepItem from '@/components/steps/StepItem';
import Tooltip from '@/components/Tooltip';

import { cn, formatDate } from '@/lib/helper';
import { BaseApproval, BaseGroupedApproval } from '@/types/api/api-general';
import { ApprovalLine } from '@/types/config/constant';

export type ApprovalStepStatus = 'APPROVED' | 'REJECTED' | 'WAITING' | 'IDLE';

export type ApprovalStepLog = {
  action_by?: string;
  date?: string;
  notes?: string | null;
};

interface ApprovalStepsProps {
  approvals: {
    name?: string;
    status: ApprovalStepStatus;
    logs?: ApprovalStepLog[];
  }[];
}

const ApprovalSteps = ({ approvals }: ApprovalStepsProps) => {
  return (
    <Steps direction='vertical' className='w-full md:steps-horizontal'>
      {approvals.map((approval, idx) => {
        const stepItemColor =
          approval.status === 'APPROVED'
            ? 'success'
            : approval.status === 'REJECTED'
              ? 'error'
              : approval.status === 'WAITING'
                ? 'warning'
                : undefined;

        const stepItemIcon =
          approval.status === 'APPROVED'
            ? 'material-symbols:check-rounded'
            : approval.status === 'REJECTED'
              ? 'material-symbols:close-rounded'
              : approval.status === 'WAITING'
                ? 'pajamas:dash-circle'
                : approval.logs && approval.logs.length > 0
                  ? 'material-symbols:info-outline-rounded'
                  : 'bxs:hourglass';

        return (
          <StepItem
            key={idx}
            color={stepItemColor}
            icon={
              <Tooltip
                color={stepItemColor}
                position='right'
                className={{
                  wrapper: 'md:tooltip-bottom',
                }}
                content={
                  <>
                    {approval.logs && approval.logs.length > 0 && (
                      <div className='flex flex-col gap-2'>
                        {approval.logs?.map((approvalLog, logIdx) => (
                          <div
                            key={logIdx}
                            className='flex flex-col text-base text-start'
                          >
                            {approvalLog.date && (
                              <span>
                                {formatDate(
                                  approvalLog.date,
                                  'YYYY-MM-DD, HH:mm:ss'
                                )}
                              </span>
                            )}
                            <span>Oleh: {approvalLog.action_by ?? '-'}</span>
                            <span>Catatan: {approvalLog.notes ?? '-'}</span>
                          </div>
                        ))}
                      </div>
                    )}
                  </>
                }
              >
                <Icon
                  icon={stepItemIcon}
                  width={24}
                  height={24}
                  className={cn({
                    invisible:
                      approval.status === 'IDLE' &&
                      (!approval.logs ||
                        (approval.logs && approval.logs.length === 0)),
                  })}
                />
              </Tooltip>
            }
          >
            {approval.name}
          </StepItem>
        );
      })}
    </Steps>
  );
};

export const formatGroupedApprovalsToApprovalSteps = (
  approvalLine: ApprovalLine,
  groupedApprovals: BaseGroupedApproval[],
  latestApproval: BaseApproval
): ApprovalStepsProps['approvals'] => {
  const formattedApprovalSteps: ApprovalStepsProps['approvals'] =
    approvalLine.map((approvalLineItem) => {
      const approvalGroup = groupedApprovals.find(
        (approvalGroupItem) =>
          approvalGroupItem.step_number === approvalLineItem.step_number
      );

      const currentStepNumber = approvalLineItem.step_number;
      const lastStepNumber =
        groupedApprovals[groupedApprovals.length - 1].step_number;

      if (!approvalGroup && currentStepNumber <= lastStepNumber) {
        throw new Error(
          `Approval dengan ${approvalLineItem.step_name} tidak ditemukan!`
        );
      }

      if (!approvalGroup) {
        const isWaiting = currentStepNumber === latestApproval.step_number + 1;
        const isPreviousApprovalRejected =
          groupedApprovals[groupedApprovals.length - 1].approvals[0].action ===
          'REJECTED';

        return {
          name: approvalLineItem.step_name,
          status: isPreviousApprovalRejected
            ? 'IDLE'
            : isWaiting
              ? 'WAITING'
              : 'IDLE',
        };
      }

      let approvalStatus: ApprovalStepStatus;

      if (approvalGroup.step_number <= latestApproval.step_number) {
        switch (approvalGroup.approvals[0].action) {
          case 'CREATED':
          case 'APPROVED':
            approvalStatus = 'APPROVED';
            break;

          case 'REJECTED':
            approvalStatus = 'REJECTED';
            break;

          default:
            approvalStatus = 'IDLE';
            break;
        }
      } else if (approvalGroup.step_number === latestApproval.step_number + 1) {
        approvalStatus = 'WAITING';
      } else {
        approvalStatus = 'IDLE';
      }

      const approvalLogs: ApprovalStepLog[] = approvalGroup.approvals.map(
        (approval) => ({
          action_by: approval.action_by.name,
          date: approval.action_at,
          notes: approval.notes,
        })
      );

      return {
        name: approvalGroup.step_name,
        status: approvalStatus,
        logs: approvalLogs,
      };
    });

  return formattedApprovalSteps;
};

export default ApprovalSteps;
