"use server";

import { redirect } from "next/navigation";
import pb from "@/lib/pocketbase";
import { cookies } from "next/headers";
import CryptoJS from 'crypto-js';

import { CheckoutSession, SignUpForm, SourceModal, Subscription, SubscriptionSession, User } from "@/types";
import { apiPrices } from "../(admin)/pricing/actions";

export async function mailchimp(formData: {
  email: string;
  first_name: string;
  last_name: string;
  phone_number?: string;
  company_size: string;
  source?: SourceModal;
}) {
  const email = formData.email;
  const mailchimpBaseUrl = process.env.NEXT_PUBLIC_MAILCHIMP_BASE_URL;
  const mailchimpApiKey = process.env.NEXT_PUBLIC_MAILCHIMP_BASE64_API_KEY;
  const mailchimpList = process.env.NEXT_PUBLIC_MAILCHIMP_LIST_ID;
  if (!mailchimpApiKey) return;
  try {
    const subscriberHash = CryptoJS.MD5(email.toLocaleLowerCase());
    const mailchimpResponse = await fetch(`${mailchimpBaseUrl}/3.0/lists/${mailchimpList}/members/${subscriberHash}`, 
    {
        method: 'PUT',
        headers: {
          "Content-Type": "application/json",
          Authorization: mailchimpApiKey,
        },
        body: JSON.stringify(
          {
            "email_address": email,
            status: "subscribed",
            merge_fields: {
              EMAIL: formData.email,
              FNAME: formData.first_name,
              LNAME: formData.last_name,
              PHONE: !formData.phone_number ? '' : formData.phone_number,
              CSIZE: formData.company_size,
              SOURCE: formData.source
            }
        }
        )
    })
    if (mailchimpResponse.status !== 200) {
      throw new Error("couldn't complete the request");
    }
    return mailchimpResponse.json();
  } catch (err) {
    throw new Error("couldn't complete the request");
  }
}

export async function signup(formData: SignUpForm) {
  const email = formData.email;
  const password = formData.password;
  const organisation = formData.organisation;
  const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL_STRING as string;
  const adminToken = process.env.NEXT_PUBLIC_POCKETBASE_ADMIN_TOKEN as string;
  try {
    const orgRes = await fetch(
      `${pocketbaseUrl}/api/collections/organisation/records`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: adminToken,
        },
        body: JSON.stringify({
          name: organisation,
        }),
      }
    );
    console.log("orgRes.status: ", orgRes.status);
    if (orgRes.status !== 200) {
      throw new Error("Failed to create organisation");
    }
    const orgData = await orgRes.json();
    console.log(orgData);
    const userRes = await fetch(
      `${pocketbaseUrl}/api/collections/user/records`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: adminToken,
        },
        body: JSON.stringify({
          firstName: formData.first_name,
          lastName: formData.last_name,
          displayName: formData.first_name + ' ' + formData.last_name,
          email: email,
          password: password,
          passwordConfirm: password,
          organisation: orgData?.id,
          role: "Admin",
          lastSeen: new Date(),
        }),
      }
    );
    console.log("userRes.status: ", userRes.status);
    if (userRes.status !== 200) {
      console.log(userRes);
      throw new Error("Failed to create user");
    }
  } catch (err) {
    if (err instanceof Error) {
      throw new Error(err.message);
    }
  }
}

export async function login(formData: { email: string; password: string }) {
  console.log('login')
  const email = formData.email as string;
  const password = formData.password as string;
  try {
    const { token, record: data } = await pb
      .collection("user")
      .authWithPassword(email, password);
    if (pb.authStore.isValid) {
      const cookie = pb.authStore.exportToCookie();

      cookies().set("pb_auth", cookie, {
        secure: true,
        path: "/",
        sameSite: "strict",
        httpOnly: true,
      });
    }
    return { success: true, error: "Failed to log in", token: token, data: data };
  } catch (error) {
    throw error;
  }
}

export async function getAuthCookie() {
  try {
    const cookie = cookies().get('pb_auth');
    pb.authStore.loadFromCookie(cookie?.value || '');
    return pb.authStore.token;
  } catch (error) {
    return undefined;
  }
}

export async function isAuthenticated() {
  try {
    const cookie = cookies().get('pb_auth');
    if(!cookie) return false;
    pb.authStore.loadFromCookie(cookie?.value || '');
    return pb.authStore.isValid || false;
  } catch (error) {
    return undefined;
  }
}

export async function logout() {
  cookies().delete("pb_auth");
  redirect('/blogs');
}

export async function createCheckoutSession(price_id: string) {
  const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL_STRING;
  if (!pocketbaseUrl) {
    throw Error('Connection Timeout');
  }
  if (!price_id) {
    throw Error('There was an error during the payment processing');
  }
  const token = await getAuthCookie();
  if (!token) {
    throw Error('Could not authenticate');
  }
  console.log('token', token);
  console.log('url ', `${pocketbaseUrl}/create-checkout-session`);
  try{
    const createCheckoutSessionResponse = await fetch(
      `${pocketbaseUrl}/create-checkout-session`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: token,
        },
        body: JSON.stringify({
          price: {
            id: price_id,
            type: "recurring"
          },
          quantity: 1
        }),
      }
    );
    console.log('createCheckoutSessionResponse.status', createCheckoutSessionResponse.status)
    if (createCheckoutSessionResponse.status !== 200) {
      throw new Error("Failed to process Request");
    }
    const createCheckoutSessionData: CheckoutSession = await createCheckoutSessionResponse.json();
    return createCheckoutSessionData;
  } catch (error) {
    throw error;
  }
}

export async function getSubscriptions() {
  const cookie = cookies().get('pb_auth');
  pb.authStore.loadFromCookie(cookie?.value || '');
  const userId = (pb.authStore.model as User).id
  const subscriptions = await pb.collection("subscription").getFullList<Subscription>({filter: `user_id="${userId}" && status="active"`});
  if (subscriptions.length === 0){
    return [];
  }
  const products = await apiPrices();
  const subscriptionWithProducts = subscriptions.map(subscription => {return {...subscription, product: products.find(product => product?.yearlyPrice?.price_id === subscription.price_id || product?.monthlyPrice?.price_id === subscription.price_id)}}) as Subscription[]
  return subscriptionWithProducts;
}

export async function createManagementSubscriptionSession() {
  const pocketbaseUrl = process.env.NEXT_PUBLIC_POCKETBASE_URL_STRING;
  if (!pocketbaseUrl) {
    throw Error('Connection Timeout');
  }
  const token = await getAuthCookie();
  if (!token) {
    throw Error('Could not authenticate');
  }
  console.log('token', token);
  console.log('url ', `${pocketbaseUrl}/create-checkout-session`);
  try{
    const createManagementSessionResponse = await fetch(
      `${pocketbaseUrl}/create-portal-link`,
      {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          Authorization: token,
        },
        body: JSON.stringify({}),
      }
    );
    console.log('createCheckoutSessionResponse.status', createManagementSessionResponse.status)
    if (createManagementSessionResponse.status !== 200) {
      throw new Error("Failed to process Request");
    }
    const createManagementSessionData: SubscriptionSession = await createManagementSessionResponse.json();
    return createManagementSessionData;
  } catch (error) {
    throw error;
  }
}