import type { ActionFunctionArgs } from "@remix-run/node";
import { json } from "@remix-run/node";
import { unauthenticated } from "../shopify.server";

export const action = async ({ request }: ActionFunctionArgs) => {
  const url = new URL(request.url);
  const shop = url.searchParams.get("shop");
  if (!shop) {
    return json({ error: "Missing shop parameter" }, { status: 400 });
  }

  const { admin } = await unauthenticated.admin(shop);
  const { storefront } = await unauthenticated.storefront(shop);

  const { accessToken, user, response, redirectTo = "/account" } = await request.json();
  const responseJson = JSON.stringify({ user, response });

  const nameParts = (user.name || "").split(" ");
  const firstName = nameParts[0] || "";
  const lastName = nameParts.slice(1).join(" ");

  const existingRes = await admin.graphql(
    `query ($email: String!) {
      customers(first: 1, query: $email) { edges { node { id } } }
    }`,
    { variables: { email: user.email } }
  );
  const existingJson = await existingRes.json();
  const existingId = existingJson.data.customers.edges[0]?.node.id;

  if (existingId) {
    await admin.graphql(
      `mutation updateCustomer($id: ID!, $firstName: String, $lastName: String, $token: String!, $response: String!) {
        customerUpdate(id: $id, input: {
          firstName: $firstName,
          lastName: $lastName,
          metafields: [
            {namespace: "social_login", key: "access_token", type: "single_line_text_field", value: $token},
            {namespace: "social_login", key: "auth_response", type: "json", value: $response}
          ]
        }) {
          customer { id }
        }
      }`,
      { variables: { id: existingId, firstName, lastName, token: accessToken, response: responseJson } }
    );
  } else {
    await admin.graphql(
      `mutation createCustomer($email: String!, $firstName: String, $lastName: String, $token: String!, $response: String!) {
        customerCreate(input: {
          email: $email,
          firstName: $firstName,
          lastName: $lastName,
          metafields: [
            {namespace: "social_login", key: "access_token", type: "single_line_text_field", value: $token},
            {namespace: "social_login", key: "auth_response", type: "json", value: $response}
          ]
        }) {
          customer { id }
        }
      }`,
      { variables: { email: user.email, firstName, lastName, token: accessToken, response: responseJson } }
    );
  }

  const tokenRes = await storefront.graphql(
    `mutation ($input: CustomerAccessTokenCreateInput!) {
      customerAccessTokenCreate(input: $input) {
        customerAccessToken { accessToken }
        customerUserErrors { message }
      }
    }`,
    { variables: { input: { email: user.email, password: accessToken } } }
  );
  const tokenJson = await tokenRes.json();
  const customerToken = tokenJson.data.customerAccessTokenCreate.customerAccessToken?.accessToken;
  if (!customerToken) {
    return json({ error: "Unable to authenticate customer" }, { status: 400 });
  }

  return json({
    redirectTo: `/account/login?customer_access_token=${customerToken}&return_url=${encodeURIComponent(redirectTo)}`
  });
};

export const loader = () => redirect("/");
