/* -------------------------------------------------------------------------- */
/*                                  Libraries                                 */
/* -------------------------------------------------------------------------- */
import React, { useEffect, useState } from "react";
/* -------------------------------------------------------------------------- */
/*                                 Components                                 */
/* -------------------------------------------------------------------------- */
import ServiceComponent from "components/containers/ServiceComponent";
import Switch from "components/controls/Switch";
import TextAction from "components/controls/TextAction";
import ThinSingleColumn from "components/layouts/ThinSingleColumn";
import { useServicesStore } from "services/data/servicesSlice";
import { useServicesViewModel } from "services/controller/servicesViewModel";
import _ from "lodash";
import { useUIStore } from "ui/data/uiSlice";
import { useSubscriptionsStore } from "subscriptions/data/subscriptionsSlice";
import { useSubscriptionsViewModel } from "subscriptions/controller/subscriptionsViewModel";
import { Service } from "services/domain/serviceEntity";
import PasswordConfirmation from "user/views/PasswordConfirmation";
import CircleLoader from "components/CircleLoader";
import Failure from "core/failure";
/* -------------------------------------------------------------------------- */
/*                                  Component                                 */
/* -------------------------------------------------------------------------- */
const Services = () => {
  const [password, setPassword] = useState<string | null>();
  const [confirmShown, toggleConfirm] = useState(false);
  const [selectedService, setSelectedService] = useState<
    Service["id"] | null
  >();
  /* ---------------------------------- Store --------------------------------- */
  const servicesStore = useServicesStore();
  const uiStore = useUIStore();
  const subscriptionsStore = useSubscriptionsStore();
  const { services, isLoading, loadServices } = useServicesViewModel({
    ...servicesStore,
    notify: uiStore.notify,
  });
  const { hasSubscription, subscribe, processingSubscription } =
    useSubscriptionsViewModel(subscriptionsStore, uiStore);
  /* ---------------------------------- Hooks --------------------------------- */
  useEffect(() => {
    loadServices();
  }, [loadServices]);

  useEffect(() => {
    if(!selectedService || password) return;
    toggleConfirm(true);
  }, [selectedService, password]);

  useEffect(() => {
    if (!selectedService) {
      return;
    }
    if (hasSubscription(selectedService)) {
      return;
    }
    if (!password) {
      return;
    }
    if (password !== null) {
      subscribe(selectedService, password!)?.catch((failure) => {
        if(Failure.isFailure(failure) && failure.status === 403) {
          setPassword(null);
        }
      });
      setSelectedService(null);
    }
  }, [selectedService, hasSubscription, subscribe, password]);

  const handleSubscription = (serviceId: Service["id"]) => {
    setSelectedService(serviceId);
  };
  /* --------------------------------- Markup --------------------------------- */
  return (
    <ThinSingleColumn>
      <div className="space-y-8">
        {!services?.length || isLoading
          ? _.times(3, (number) => (
              <ServiceComponent key={number} variant="gray" clipText="tch">
                <div className="flex items-center justify-between">
                  <div>
                    <div className="text-lg font-bold">Techpal</div>
                    <TextAction variant="gray">about service</TextAction>
                  </div>
                  <div>
                    <Switch enabled={false} onChange={() => null} />
                  </div>
                </div>
              </ServiceComponent>
            ))
          : services!.map((item, index) => {
              return (
                <ServiceComponent
                  key={index}
                  variant={item.variant ?? "gray"}
                  clipText={item.shortName}
                >
                  <div className="flex items-center justify-between">
                    <div>
                      <div className="text-lg font-bold">{item.name}</div>
                      <TextAction variant="gray">about service</TextAction>
                    </div>
                    <div>
                      {processingSubscription(item.id) ? (
                        <div className="h-6 w-6">
                          <CircleLoader />
                        </div>
                      ) : (
                        <Switch
                          enabled={hasSubscription(item.id)}
                          onChange={() => handleSubscription(item.id)}
                        />
                      )}
                    </div>
                  </div>
                </ServiceComponent>
              );
            })}
      </div>
      {confirmShown && selectedService && (
        <PasswordConfirmation
          onSubmit={(p) => setPassword(p)}
          isShown={true}
          onClose={() => toggleConfirm(false)}
        />
      )}
    </ThinSingleColumn>
  );
};

export default Services;
