import clsx from "clsx";
import { useEffect, useState } from "react";
import {
  createBannerURL,
  createFileUploadPageURL,
  createIconURL,
  createProfilePageURL,
} from "#lib/urls";
import { ImageBackground, ImageLink } from "#components/images";
import { paysites } from "#entities/paysites";
import {
  addProfileToFavourites,
  isFavouriteProfile,
  isRegisteredAccount,
  removeProfileFromFavourites,
} from "#entities/account";

interface IProps {
  service: string;
  profileID: string;
  profileName?: string;
}

/**
 * TODO: asset imports instead of literal paths
 */
const paysiteIcons = {
  patreon: "/static/patreon.svg",
  fanbox: "/static/fanbox.svg",
  boosty: "/static/boosty.svg",
  gumroad: "/static/gumroad.svg",
  subscribestar: "/static/subscribestar.png",
  dlsite: "/static/dlsite.png",
  fantia: "/static/fantia.png",
  onlyfans: "/static/onlyfans.svg",
  fansly: "/static/fansly.svg",
  candfans: "/static/candfans.png",
} as const;

export function ProfileHeader({ service, profileID, profileName }: IProps) {
  const artistIcon = createIconURL(service, profileID);
  const artistBanner = createBannerURL(service, profileID);
  const externalProfileURL = paysites[service].user.profile(profileID);
  const paysiteIconURL = paysiteIcons[service as keyof typeof paysiteIcons];

  return (
    <header
      className="user-header"
      itemScope
      itemType="https://schema.org/Person"
    >
      <ImageBackground
        className="user-header__background"
        src={artistBanner}
        isLazy={false}
      />
      {/* TODO: remove self-referencing link */}
      <ImageLink
        url={String(createProfilePageURL({ service, profileID }))}
        src={artistIcon}
        isLazy={false}
        isNoop={false}
        className="user-header__avatar"
      />

      <div className="user-header__info">
        <h1 id="user-header__info-top" className="user-header__name">
          <a
            className="user-header__profile"
            href={externalProfileURL}
            target="_blank"
            rel="noreferrer"
            itemProp="url"
          >
            <span className="user-header__profile-image">
              <img src={paysiteIconURL} />
            </span>
            <span itemProp="name">{profileName}</span>
          </a>
        </h1>

        <div className="user-header__actions">
          <a
            className="user-header__upload"
            href={String(createFileUploadPageURL(service, profileID))}
          >
            <span>Upload file</span>
          </a>

          <FavouriteButton service={service} profileID={profileID} />
        </div>
      </div>
    </header>
  );
}

interface IFavouriteButtonProps {
  service: string;
  profileID: string;
}

function FavouriteButton({ service, profileID }: IFavouriteButtonProps) {
  const [isFavourited, switchFavourite] = useState(false);
  const [isLoading, switchLoading] = useState(true);
  const renderKey = `${service}${profileID}`;

  useEffect(() => {
    (async () => {
      try {
        switchLoading(true);
        const isLoggedIn = await isRegisteredAccount();

        if (!isLoggedIn) {
          return;
        }

        const result = await isFavouriteProfile(service, profileID);

        switchFavourite(result);
      } catch (error) {
        // TODO: better error handling
        console.error(error);
      } finally {
        switchLoading(false);
      }
    })();
  }, [service, profileID]);

  async function handleFavouriting() {
    try {
      switchLoading(true);
      await addProfileToFavourites(service, profileID);
      switchFavourite(true);
    } catch (error) {
      // TODO: better error handling
      console.error(error);
    } finally {
      switchLoading(false);
    }
  }

  async function handleUnfavouriting() {
    try {
      switchLoading(true);
      await removeProfileFromFavourites(service, profileID);
      switchFavourite(false);
    } catch (error) {
      // TODO: better error handling
      console.error(error);
    } finally {
      switchLoading(false);
    }
  }

  return !isFavourited ? (
    <button
      key={renderKey}
      className={clsx(
        "user-header__favourite",
        isLoading && "user-header__favourite--loading"
      )}
      type="button"
      disabled={isLoading}
      onClick={handleFavouriting}
    >
      <span className="user-header__fav-icon">☆</span>
      <span className="user-header__fav-text">Favorite</span>
    </button>
  ) : (
    <button
      key={renderKey}
      className={clsx(
        "user-header__favourite",
        "user-header__favourite--unfav",
        isLoading && "user-header__favourite--loading"
      )}
      type="button"
      disabled={isLoading}
      onClick={handleUnfavouriting}
    >
      <span className="user-header__fav-icon">★</span>
      <span className="user-header__fav-text">Unfavorite</span>
    </button>
  );
}
