import React, { useEffect, useMemo, useState } from 'react';
import axios from 'axios';
import { useFormikContext } from 'formik';
import CardBox from './CardBox';
import {
  calculateJobLogPayPreview,
  formatCurrency,
  formatDecimal,
  hasPayTypeDetails,
  hasWorkersCompDetails,
  resolveEntityId,
} from '../helpers/jobLogPayPreview';

type Props = {
  payTypeOptions?: any[];
};

const findById = (items: any[] = [], id: string | null) => items.find((item) => item?.id === id) || null;

export default function JobLogPayPreview({ payTypeOptions = [] }: Props) {
  const { values } = useFormikContext<any>();
  const [payTypeDetails, setPayTypeDetails] = useState<any>(null);
  const [workersCompClassDetails, setWorkersCompClassDetails] = useState<any>(null);

  const selectedPayTypeId = resolveEntityId(values?.pay_type);
  const selectedWorkersCompClassId = resolveEntityId(values?.workersCompClass);

  const selectedPayTypeFromOptions = useMemo(
    () => findById(payTypeOptions, selectedPayTypeId),
    [payTypeOptions, selectedPayTypeId],
  );

  useEffect(() => {
    let active = true;

    if (hasPayTypeDetails(values?.pay_type)) {
      setPayTypeDetails(values.pay_type);
      return () => {
        active = false;
      };
    }

    if (selectedPayTypeFromOptions) {
      setPayTypeDetails(selectedPayTypeFromOptions);
      return () => {
        active = false;
      };
    }

    if (!selectedPayTypeId) {
      setPayTypeDetails(null);
      return () => {
        active = false;
      };
    }

    axios
      .get(`/pay_types/${selectedPayTypeId}`)
      .then(({ data }) => {
        if (active) {
          setPayTypeDetails(data);
        }
      })
      .catch((error) => {
        console.error('Failed to fetch pay type for job log preview:', error);
        if (active) {
          setPayTypeDetails(null);
        }
      });

    return () => {
      active = false;
    };
  }, [selectedPayTypeFromOptions, selectedPayTypeId, values?.pay_type]);

  useEffect(() => {
    let active = true;

    if (hasWorkersCompDetails(values?.workersCompClass)) {
      setWorkersCompClassDetails(values.workersCompClass);
      return () => {
        active = false;
      };
    }

    if (!selectedWorkersCompClassId) {
      setWorkersCompClassDetails(null);
      return () => {
        active = false;
      };
    }

    axios
      .get(`/workers_comp_classes/${selectedWorkersCompClassId}`)
      .then(({ data }) => {
        if (active) {
          setWorkersCompClassDetails(data);
        }
      })
      .catch((error) => {
        console.error('Failed to fetch workers comp class for job log preview:', error);
        if (active) {
          setWorkersCompClassDetails(null);
        }
      });

    return () => {
      active = false;
    };
  }, [selectedWorkersCompClassId, values?.workersCompClass]);

  const preview = useMemo(
    () =>
      calculateJobLogPayPreview({
        payType: payTypeDetails,
        workersCompClass: workersCompClassDetails,
        hoursConducted: values?.hours_conducted,
        clientPaid: values?.client_paid,
      }),
    [payTypeDetails, workersCompClassDetails, values?.client_paid, values?.hours_conducted],
  );

  return (
    <CardBox className="mb-6 border border-blue-100 bg-blue-50/70 dark:border-dark-700 dark:bg-dark-800">
      <div className="space-y-4">
        <div className="flex flex-col gap-1 md:flex-row md:items-end md:justify-between">
          <div>
            <p className="text-xs font-semibold uppercase tracking-wide text-blue-700 dark:text-blue-300">
              Earnings Preview
            </p>
            <h3 className="text-lg font-bold">Live estimate for this job</h3>
          </div>
          <div className="text-left md:text-right">
            <p className="text-xs uppercase text-gray-500 dark:text-gray-400">Estimated Job Pay</p>
            <p className="text-2xl font-bold text-green-700 dark:text-green-400">
              {formatCurrency(preview.estimatedPay)}
            </p>
          </div>
        </div>

        <div className="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-4">
          <div className="rounded-lg border border-white/80 bg-white/80 p-3 dark:border-dark-700 dark:bg-dark-900">
            <p className="text-xs uppercase text-gray-500 dark:text-gray-400">Pay Type</p>
            <p className="font-semibold capitalize">{preview.payTypeName}</p>
          </div>

          <div className="rounded-lg border border-white/80 bg-white/80 p-3 dark:border-dark-700 dark:bg-dark-900">
            <p className="text-xs uppercase text-gray-500 dark:text-gray-400">Pay Method</p>
            <p className="font-semibold capitalize">{preview.payMethod || 'Not selected'}</p>
          </div>

          <div className="rounded-lg border border-white/80 bg-white/80 p-3 dark:border-dark-700 dark:bg-dark-900">
            <p className="text-xs uppercase text-gray-500 dark:text-gray-400">
              {preview.payMethod === 'commission' ? 'Client Paid' : 'Hours'}
            </p>
            <p className="font-semibold">
              {preview.payMethod === 'commission'
                ? formatCurrency(preview.clientAmount)
                : formatDecimal(preview.hours)}
            </p>
          </div>

          <div className="rounded-lg border border-white/80 bg-white/80 p-3 dark:border-dark-700 dark:bg-dark-900">
            <p className="text-xs uppercase text-gray-500 dark:text-gray-400">Rate</p>
            <p className="font-semibold">
              {preview.payMethod === 'commission'
                ? `${formatDecimal(preview.commissionRate)}%`
                : formatCurrency(preview.hourlyRate)}
            </p>
          </div>
        </div>

        <div className="rounded-lg border border-dashed border-blue-200 bg-white/80 p-3 dark:border-dark-700 dark:bg-dark-900">
          <p className="text-xs uppercase text-gray-500 dark:text-gray-400">Calculation</p>
          <p className="font-medium">
            {preview.formulaLabel}
            {preview.hasEstimate ? ` = ${formatCurrency(preview.estimatedPay)}` : ''}
          </p>
        </div>

        {preview.workersCompName && (
          <div className="rounded-lg border border-white/80 bg-white/80 p-3 dark:border-dark-700 dark:bg-dark-900">
            <p className="text-xs uppercase text-gray-500 dark:text-gray-400">Workers Comp Estimate</p>
            <p className="font-semibold">
              {preview.workersCompName} · {formatDecimal(preview.workersCompPercentage)}% ·{' '}
              {formatCurrency(preview.workersCompAmount)}
            </p>
            <p className="mt-1 text-xs text-gray-500 dark:text-gray-400">
              This is shown for visibility only and does not reduce the employee pay preview.
            </p>
          </div>
        )}
      </div>
    </CardBox>
  );
}
