import { error, fail, redirect } from "@sveltejs/kit";
import { validateData } from "$lib/utils";
import { loginUserSchema, registerUserSchema } from "$lib/schemas";


const transactionTypeMap = {
  "P-Purchase": "Bought",
  "A-Award": "Grant",
  "D-Return": "Grant",
  "G-Gift": "Grant",
  "S-Sale": "Sold",
  "M-Exempt": "Exercise",
  "X-InTheMoney": "Exercise",
  "C-Conversion": "Exercise",
  "F-InKind": "Sold",
  "J-Other": (item) => {
    if (item.acquistionOrDisposition === "D") {
      return "Sold";
    } else if (item.acquistionOrDisposition === "A") {
      return "Bought";
    } else {
      return "Other";
    }
  },
  "": "n/a",
};

export const load = async ({ locals, params }) => {
  const { apiURL, apiKey, user } = locals;

  const getInsiderTrading = async () => {
    const postData = {
      ticker: params.tickerID,
    };

    // make the POST request to the endpoint
    const response = await fetch(apiURL + "/insider-trading", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-API-KEY": apiKey,
      },
      body: JSON.stringify(postData),
    });

    let output = await response.json();

    output = user?.tier !== "Pro" ? output?.slice(0, 6) : output;

    output = output?.reduce((acc, item) => {
      const newTransactionType =
        typeof transactionTypeMap[item?.transactionType] === "function"
          ? transactionTypeMap[item?.transactionType](item)
          : transactionTypeMap[item?.transactionType];

      // Only include items with 'Bought' or 'Sold'
      if (newTransactionType === "Bought" || newTransactionType === "Sold") {
        const value = item?.securitiesTransacted * item?.price;
        if (value > 0) {
          acc.push({
            ...item,
            transactionType: newTransactionType,
            value: value, // new key 'value'
          });
        }
      }

      return acc;
    }, []);
    return output;
  };

  /*
  const getInsiderTradingStatistics = async () => {
    const postData = {
      ticker: params.tickerID,
    };

    // make the POST request to the endpoint
    const response = await fetch(apiURL + "/insider-trading-statistics", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-API-KEY": apiKey,
      },
      body: JSON.stringify(postData),
    });

    const output = await response?.json();

    return output;
  };
  */

  // Make sure to return a promise
  return {
    getInsiderTrading: await getInsiderTrading(),
    //getInsiderTradingStatistics: await getInsiderTradingStatistics(),
  };
};



export const actions = {
  login: async ({ url, request, locals }) => {

        const path = url?.href?.replace("/oauth2","")

    const { formData, errors } = await validateData(
      await request.formData(),
      loginUserSchema,
    );

    if (errors) {
      return fail(400, {
        data: formData,
        errors: errors.fieldErrors,
      });
    }

    try {
      await locals.pb
        .collection("users")
        .authWithPassword(formData.email, formData.password);

      /*	
			if (!locals.pb?.authStore?.model?.verified) {
				locals.pb.authStore.clear();
				return {
					notVerified: true,
				};
			}
			*/
    } catch (err) {
      console.log("Error: ", err);
      error(err.status, err.message);
    }

    redirect(302, path);
  },

  register: async ({ url, locals, request }) => {
        const path = url?.href?.replace("/oauth2","")

    const { formData, errors } = await validateData(
      await request.formData(),
      registerUserSchema,
    );

    if (errors) {
      return fail(400, {
        data: formData,
        errors: errors.fieldErrors,
      });
    }

    try {
      let newUser = await locals.pb.collection("users").create(formData);
      /*
await locals.pb?.collection('users').update(
				newUser?.id, {
					'freeTrial' : true,
					'tier': 'Pro', //Give new users a free trial for the Pro Subscription
			});
*/
      await locals.pb.collection("users")?.requestVerification(formData.email);
    } catch (err) {
      console.log("Error: ", err);
      error(err.status, err.message);
    }

    try {
      await locals.pb
        .collection("users")
        .authWithPassword(formData.email, formData.password);
    } catch (err) {
      console.log("Error: ", err);
      error(err.status, err.message);
    }

    redirect(303, path);
  },

   oauth2: async ({ url, locals, request, cookies }) => {

    const path = url?.href?.replace("/oauth2","")
    const authMethods = (await locals?.pb
      ?.collection("users")
      ?.listAuthMethods())?.oauth2;


    const data = await request?.formData();
    const providerSelected = data?.get("provider");

    if (!authMethods) {
      return {
        authProviderRedirect: "",
        authProviderState: "",
      };
    }
    const redirectURL = `${url.origin}/oauth`;

    const targetItem = authMethods?.providers?.findIndex(
      (item) => item?.name === providerSelected,
    );
    //console.log("==================")
    //console.log(authMethods.authProviders)
    //console.log('target item is: ', targetItem)

    const provider = authMethods.providers[targetItem];
    const authProviderRedirect = `${provider.authUrl}${redirectURL}`;
    const state = provider.state;
    const verifier = provider.codeVerifier;

    
    
    cookies.set("state", state, {
      httpOnly: true,
      sameSite: "lax",
      secure: true,
      path: "/",
      maxAge: 60 * 60,
    });

    cookies.set("verifier", verifier, {
      httpOnly: true,
      sameSite: "lax",
      secure: true,
      path: "/",
      maxAge: 60 * 60,
    });

    cookies.set("provider", providerSelected, {
      httpOnly: true,
      sameSite: "lax",
      secure: true,
      path: "/",
      maxAge: 60 * 60,
    });

    cookies.set("path", path, {
      httpOnly: true,
      sameSite: "lax",
      secure: true,
      path: "/",
      maxAge: 60,
    });

    redirect(302, authProviderRedirect);
  },

};
