import React, { Component } from 'react';
import { __ } from '@wordpress/i18n';
import { BriefcaseBusiness } from 'lucide-react';
import Skeleton from '@mui/material/Skeleton';
import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';

class ServiceStep extends Component {
  state = {
    animateIn: false,
  };

  componentDidMount() {
    if (this.getShowLocationStep()) {
      const { state } = this.props;

      const hasServicesForLocation = Array.isArray(state.categorizedServices) && state.categorizedServices.length > 0;
      if (!hasServicesForLocation && state.locationId) {
        this.resetForLocation();
        this.fetchServicesByLocationIfNeeded();
      }
    }
    const isLoading = this.getIsLoading(this.props.state, this.getShowLocationStep());
    this.restartAnimation(isLoading);
  }

  componentDidUpdate(prevProps) {
    const { state } = this.props;
    const prevState = prevProps.state;
    const showLocationStep = this.getShowLocationStep();

    if (showLocationStep && state.locationId !== prevState.locationId) {
      this.resetForLocation();
      this.fetchServicesByLocationIfNeeded();
    }

    if (showLocationStep && !state.serviceStopRerendering && state.serviceStopRerendering !== prevState.serviceStopRerendering) {
      this.fetchServicesByLocationIfNeeded();
    }

    const categories = this.getCategories(state);
    const prevCategories = this.getCategories(prevState);
    const isLoading = this.getIsLoading(state, showLocationStep);
    const wasLoading = this.getIsLoading(prevState, showLocationStep);
    const categorizedChanged = state.categorizedServices !== prevState.categorizedServices;
    const servicesChanged = state.services !== prevState.services;

    if (
      isLoading !== wasLoading ||
      categories.length !== prevCategories.length ||
      categorizedChanged ||
      servicesChanged ||
      state.locationId !== prevState.locationId ||
      state.serviceId !== prevState.serviceId
    ) {
      this.restartAnimation(isLoading);
    }
  }

  componentWillUnmount() {
    if (this.animationFrame) {
      cancelAnimationFrame(this.animationFrame);
    }
  }

  animationFrame = null;

  getShowLocationStep = () => (
    window.BookifyPro &&
    window.BookifyPro.Light &&
    window.BookifyPro.Light.LocationStep &&
    wpbApp?.HideLocations !== 'true' &&
    wpbApp?.locationsCount > 0
  );

  getCategories = (state) => {
    if (Array.isArray(state.categorizedServices) && state.categorizedServices.length > 0) {
      return state.categorizedServices;
    }

    if (Array.isArray(state.categories) && Array.isArray(state.services)) {
      return state.categories
        .map((category) => {
          const services = state.services
            .filter((service) => service.service_category === category.id)
            .map((service) => ({
              id: service.id,
              name: service.service_name || service.name,
              category: category.category_name,
              price: Number(service.service_price ?? service.price ?? 0),
              duration: service.service_duration || service.duration || '',
              image: service.service_img || service.image || '',
            }));
          return services.length > 0 ? { name: category.category_name, services } : null;
        })
        .filter(Boolean);
    }
    return [];
  };

  getIsLoading = (state, showLocationStep) =>
    state.dataLoading || (showLocationStep ? state.serviceByLocaionLoading : false);

  resetForLocation = () => {
    const { updateInput } = this.props;
    updateInput({
      serviceStopRerendering: false,
      serviceByLocaionLoading: true,
      categorizedServices: [],
    });
  };

  fetchServicesByLocationIfNeeded = () => {
    const { state, updateInput } = this.props;
    if (!this.getShowLocationStep()) return;
    if (state.serviceStopRerendering) return;

    const pickFirst = (val) => (Array.isArray(val) ? val[0] : val);
    let locationId = state.locationId;
    if (locationId === null && wpbApp.HideLocations === 'true') {
      locationId = pickFirst(wpbApp.Locations);
    }
    if (locationId === null || locationId === undefined) {
      updateInput({ serviceByLocaionLoading: false });
      return;
    }

    const dataToSend = {
      location_id: pickFirst(locationId),
      services: wpbApp.Services,
    };

    fetch(`${wpbApp.root}bookify/frontend/v1/get-services-by-location`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-WP-Nonce': wpbApp.nonce,
      },
      body: JSON.stringify(dataToSend),
    })
      .then((response) => response.json())
      .then((data) => {
        const categorizedServices =
          (data.services || []).map((category) => ({
            name: category.category_name,
            services: (category.services || []).map((service) => ({
              id: service.id,
              name: service.service_name || service.name,
              category: category.category_name,
              price: Number(service.service_price ?? service.price ?? 0),
              duration: service.service_duration || service.duration || '',
              image: service.service_img || service.image || '',
            })),
          })) || [];

        updateInput({
          categorizedServices,
          serviceByLocaionLoading: false,
          serviceStopRerendering: true,
        });
      })
      .catch((error) => {
        console.error('Error fetching services by location:', error);
        updateInput({ serviceByLocaionLoading: false });
      });
  };

  restartAnimation = (isLoading) => {
    if (isLoading) {
      this.setState({ animateIn: false });
      return;
    }
    this.setState({ animateIn: false });
    if (this.animationFrame) {
      cancelAnimationFrame(this.animationFrame);
    }
    this.animationFrame = requestAnimationFrame(() => this.setState({ animateIn: true }));
  };

  selectService = (service) => {
    const { updateInput, onNext } = this.props;
    updateInput({
      serviceId: service.id,
      serviceName: service.name,
      servicePrice: service.price,
      staffId: null,
      staffName: '',
      date: null,
      slot: null,
      slots: [],
      appointmentId: null,
      total: service.price,
    });

    if (onNext) {
      onNext();
    }
  };

  handleBack = () => {
    const { updateInput, onBack } = this.props;
    updateInput({
      serviceId: null,
      serviceName: '',
      categorizedServices: [],
      serviceStopRerendering: false,
    });
    if (onBack) {
      onBack();
    }
  };

  render() {
    const { state, onNext } = this.props;
    const categories = this.getCategories(state);
    const showLocationStep = this.getShowLocationStep();
    const isLoading = this.getIsLoading(state, showLocationStep);
    const showBackButton = Boolean(window.BookifyPro && window.BookifyPro.Light && window.BookifyPro.Light.LocationStep && wpbApp.HideLocations === "false" && wpbApp.locationsCount > 0);

    return (
      <>
        <div className="flex flex-col h-auto min-h-[436px] space-y-8 p-5">
          {isLoading ? (
            Array.from(new Array(2)).map((_, index) => (
              <Box key={index}>
                <Skeleton variant="text" animation="wave" width={150} />
                <Grid container spacing={2} sx={{ pt: 1 }}>
                  <Grid item xs={6}>
                    <Skeleton variant="rectangular" animation="wave" width="100%" height={50} />
                  </Grid>
                  <Grid item xs={6}>
                    <Skeleton variant="rectangular" animation="wave" width="100%" height={50} />
                  </Grid>
                  <Grid item xs={6}>
                    <Skeleton variant="rectangular" animation="wave" width="100%" height={50} />
                  </Grid>
                </Grid>
              </Box>
            ))
          ) : categories.length === 0 ? (
            <div className="text-slate-400 text-sm">{__('No Category or Service were found!', 'bookify')}</div>
          ) : (
            categories.map((cat, catIndex) => {
              const catDelay = `${catIndex * 120}ms`;

              return (
                <div
                  key={cat.name}
                  className="space-y-3"
                  style={{
                    transition: 'opacity 600ms ease, transform 600ms ease',
                    transitionDelay: catDelay,
                    transform: this.state.animateIn ? 'translateY(0)' : 'translateY(24px)',
                    opacity: this.state.animateIn ? 1 : 0,
                  }}
                >
                  <h3 className="text-xs font-bold uppercase tracking-widest text-slate-400">{cat.name}</h3>
                  <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                    {cat.services.map((service, serviceIndex) => {
                      const isSelected = state.serviceId === service.id;
                      const delay = `${serviceIndex * 70}ms`;

                      return (
                        <button
                          key={service.id}
                          onClick={() => this.selectService(service)}
                          className={`relative flex items-center text-left px-4 py-3 rounded-lg border outline-none ${isSelected
                            ? 'border-blue-600 bg-blue-50/50 shadow-md'
                            : 'border-slate-150 bg-white hover:border-blue-100 hover:bg-slate-50'
                            }`}
                          style={{
                            transition: 'opacity 600ms ease, transform 600ms ease',
                            transitionDelay: delay,
                            transform: this.state.animateIn ? 'translateY(0)' : 'translateY(24px)',
                            opacity: this.state.animateIn ? 1 : 0,
                          }}
                        >
                          <div className="mr-4">
                            {service.image ? (
                              <img
                                src={service.image}
                                alt={service.name}
                                className="w-10 h-10 rounded-md object-cover border border-slate-100"
                              />
                            ) : (
                              <div
                                className={`p-2 rounded-md transition-colors ${isSelected
                                  ? 'bg-blue-600 text-white'
                                  : 'bg-slate-100 text-slate-500 hover:bg-blue-100 hover:text-blue-600'
                                  }`}
                              >
                                <BriefcaseBusiness size={20} className={isSelected ? 'opacity-100' : 'opacity-20'} />
                              </div>
                            )}
                          </div>
                          <div className="flex-1">
                            <h4 className="font-medium text-sm pb-1">{service.name}</h4>

                          </div>
                          {isSelected && (
                            <div className="absolute top-[6px] right-[6px] text-blue-600">
                              <div className="w-2 h-2 rounded-full bg-blue-600" />
                            </div>
                          )}
                        </button>
                      );
                    })}
                  </div>
                </div>
              );
            })
          )}
        </div>

        <div className="px-[20px] py-[10px] flex justify-end sticky bottom-0 bg-white border-t border-slate-150">
          {showBackButton && (
            <button
              onClick={this.handleBack}
              className="px-[16px] py-[6px] text-slate-400 text-sm font-bold rounded-sm hover:bg-slate-50 transition-colors"
            >
              {__('Back', 'bookify')}
            </button>
          )}
          <button
            disabled={!state.serviceId}
            onClick={onNext}
            className="px-[16px] py-[6px] bg-blue-600 text-white text-sm font-bold rounded-sm shadow-xl shadow-blue-200 hover:bg-blue-700 disabled:opacity-50 disabled:shadow-none transition-all hover:scale-[1.02] active:scale-95"
          >
            {__('Next', 'bookify')}
          </button>
        </div>
      </>
    );
  }
}

export default ServiceStep;
