import { useEffect, useState } from 'react';

import WizardProgress from '@/components/newcover/WizardProgress';
import WizardStep from '@/components/newcover/WizardStep';
import { steps } from '@/components/newcover/wizardConfig';

import { customerService } from '@/services/customerService';
import { componentService } from '@/services/componentService';
import { projectService } from '@/services/projectService';

const profileSelections = limb => {
  if (!limb) return {};

  const configuration =
    String(limb.configuration || '');

  const lowerConfiguration =
    configuration.toLowerCase();

  const side =
    limb.side
    || (
      lowerConfiguration.startsWith('left')
        ? 'Left'
        : lowerConfiguration.startsWith('right')
          ? 'Right'
          : ''
    );

  const rawLevel =
    limb.amputation_level
    || configuration.replace(
      /^(Left|Right)\s+/i,
      ''
    );

  const amputationLevel =
    rawLevel
      ? rawLevel
          .split(/[\s-]+/)
          .map(word =>
            word
              ? word[0].toUpperCase()
                + word.slice(1).toLowerCase()
              : word
          )
          .join('-')
      : '';

  const limbRegion =
    limb.limb_region
    || (
      /elbow|wrist|shoulder|upper limb/i.test(
        configuration
      )
        ? 'Upper limb'
        : 'Lower limb'
    );

  return {
    interface_type:
      limb.interface_type || '',
    limb_region: limbRegion,
    amputation_level:
      amputationLevel || '',
    side,
    prosthesis_configuration: [
      limb.interface_type,
      limbRegion,
      amputationLevel,
      side,
    ]
      .filter(Boolean)
      .join(' | '),
  };
};

export default function NewCoverWizard({
  onCreated,
}) {
  const [step, setStep] = useState(1);
  const [customers, setCustomers] = useState([]);
  const [limbs, setLimbs] = useState([]);
  const [components, setComponents] = useState([]);

  const [data, setData] = useState({
    component_uuids: [],
    components_pending: false,
    status: 'Awaiting measurements',
  });

  const [busy, setBusy] = useState(false);
  const [error, setError] = useState('');

  useEffect(() => {
    Promise.all([
      customerService.list(),
      componentService.list(),
    ]).then(([customerRecords, componentRecords]) => {
      setCustomers(
        customerRecords.filter(
          value =>
            value.record_state === 'active'
        )
      );

      setComponents(
        componentRecords.filter(
          value =>
            value.record_state === 'active'
        )
      );
    });
  }, []);

  useEffect(() => {
    if (
      data.customer_uuid
      && data.customer_uuid !== 'new'
    ) {
      customerService
        .history(data.customer_uuid)
        .then(history =>
          setLimbs(
            history.limbs.filter(
              value =>
                value.record_state === 'active'
            )
          )
        );
    } else {
      setLimbs([]);
    }
  }, [data.customer_uuid]);

  useEffect(() => {
    if (
      !data.limb_profile_uuid
      || data.limb_profile_uuid === 'new'
    ) {
      return;
    }

    const limb = limbs.find(
      item =>
        item.uuid === data.limb_profile_uuid
    );

    if (!limb) return;

    setData(current => ({
      ...current,
      ...profileSelections(limb),
    }));
  }, [data.limb_profile_uuid, limbs]);

  const create = async () => {
    setBusy(true);
    setError('');

    try {
      let customerUuid = data.customer_uuid;

      if (customerUuid === 'new') {
        const customer =
          await customerService.create(
            {
              ...data.newCustomer,
              approval_status: 'Not requested',
            },
            'Ray'
          );

        customerUuid = customer.uuid;
      }

      let limbUuid = data.limb_profile_uuid;

      if (limbUuid === 'new') {
        const newLimb = {
          ...data.newLimb,
          customer_uuid: customerUuid,
          interface_type:
            data.interface_type,
          limb_region:
            data.limb_region,
          amputation_level:
            data.amputation_level,
          side:
            data.side,
          configuration:
            `${data.side} ${data.amputation_level.toLowerCase()}`,
          data_label: 'WORKSHOP RECORD',
        };

        const limb =
          await customerService.createLimb(
            newLimb,
            'Ray'
          );

        limbUuid = limb.uuid;
      }

      const project =
        await projectService.create(
          {
            ...data,
            customer_uuid: customerUuid,
            limb_profile_uuid: limbUuid,
            newCustomer: undefined,
            newLimb: undefined,
          },
          'Ray'
        );

      onCreated(project);
    } catch (creationError) {
      setError(
        creationError.message
        || 'Project could not be created.'
      );
    } finally {
      setBusy(false);
    }
  };

  const hasConfiguration =
    !!data.interface_type
    && !!data.limb_region
    && !!data.amputation_level
    && !!data.side;

  const hasComponents =
    (data.component_uuids || []).length > 0
    || data.components_pending === true;

  const validByStep = [
    true,

    !!data.customer_uuid
      && (
        data.customer_uuid !== 'new'
        || !!data.newCustomer?.full_name
      ),

    !!data.limb_profile_uuid
      && (
        data.limb_profile_uuid !== 'new'
        || !!data.newLimb?.profile_name
      ),

    hasConfiguration,

    hasComponents,

    !!data.measurement_method,

    !!data.cover_boundaries,

    !!data.sensitive_area_summary,

    !!data.design_preferences,

    true,

    !!data.safety_boundary_accepted,
  ];

  const valid = validByStep[step];

  return (
    <div className="panel mx-auto max-w-3xl p-5 sm:p-8">
      <WizardProgress
        step={step}
        labels={steps}
      />

      <h2 className="mb-5 text-2xl font-semibold text-white">
        {steps[step - 1]}
      </h2>

      <WizardStep
        step={step}
        data={data}
        setData={setData}
        customers={customers}
        limbs={limbs}
        components={components}
      />

      {!valid && (
        <p
          role="alert"
          className="mt-4 text-sm text-amber-300"
        >
          Complete the required selection or
          information before continuing.
        </p>
      )}

      {error && (
        <p
          role="alert"
          className="mt-4 text-sm text-red-300"
        >
          {error}
        </p>
      )}

      <div className="mt-8 flex justify-between">
        <button
          disabled={step === 1 || busy}
          onClick={() => setStep(step - 1)}
          className="btn-secondary"
        >
          Back
        </button>

        {step < 10 ? (
          <button
            disabled={!valid || busy}
            onClick={() => setStep(step + 1)}
            className="btn-primary"
          >
            Continue
          </button>
        ) : (
          <button
            disabled={!valid || busy}
            onClick={create}
            className="btn-primary"
          >
            {busy
              ? 'Creating...'
              : 'Create project'}
          </button>
        )}
      </div>
    </div>
  );
}
