import { createClient } from "https://esm.sh/@supabase/supabase-js@2";
import { z } from "../_shared/deps.ts";
import { parseJsonBody } from "../_shared/validate.ts";

const BodySchema = z.object({
  phone: z.string().regex(/^1\d{10}$/, "请输入有效的11位手机号"),
  code: z.string().regex(/^\d{4,6}$/, "验证码格式无效"),
});

const corsHeaders = {
  "Access-Control-Allow-Origin": "*",
  "Access-Control-Allow-Headers":
    "authorization, x-client-info, apikey, content-type",
};

function percentEncode(str: string): string {
  return encodeURIComponent(str)
    .replace(/!/g, "%21")
    .replace(/'/g, "%27")
    .replace(/\(/g, "%28")
    .replace(/\)/g, "%29")
    .replace(/\*/g, "%2A");
}

async function buildAliyunSignature(
  method: string,
  params: Record<string, string>,
  secret: string
): Promise<string> {
  const sorted = Object.keys(params).sort();
  const query = sorted
    .map((k) => `${percentEncode(k)}=${percentEncode(params[k])}`)
    .join("&");
  const sts = `${method}&${percentEncode("/")}&${percentEncode(query)}`;
  const key = new TextEncoder().encode(secret + "&");
  const data = new TextEncoder().encode(sts);
  const ck = await crypto.subtle.importKey(
    "raw",
    key,
    { name: "HMAC", hash: "SHA-1" },
    false,
    ["sign"]
  );
  const sig = await crypto.subtle.sign("HMAC", ck, data);
  return btoa(String.fromCharCode(...new Uint8Array(sig)));
}

Deno.serve(async (req) => {
  if (req.method === "OPTIONS")
    return new Response(null, { headers: corsHeaders });

  try {
    const parsed = await parseJsonBody(req, BodySchema);
    if (!parsed.ok) {
      return new Response(
        JSON.stringify({ error: parsed.message, details: parsed.issues }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }
    const { phone, code } = parsed.data;

    const supabase = createClient(
      Deno.env.get("SUPABASE_URL")!,
      Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!
    );

    const accessKeyId = Deno.env.get("ALIYUN_ACCESS_KEY_ID")!;
    const accessKeySecret = Deno.env.get("ALIYUN_ACCESS_KEY_SECRET")!;

    const now = new Date();
    const params: Record<string, string> = {
      Action: "CheckSmsVerifyCode",
      Version: "2017-05-25",
      Format: "JSON",
      AccessKeyId: accessKeyId,
      SignatureMethod: "HMAC-SHA1",
      Timestamp: now.toISOString().replace(/\.\d{3}Z$/, "Z"),
      SignatureVersion: "1.0",
      SignatureNonce: crypto.randomUUID(),
      PhoneNumber: phone,
      VerifyCode: code,
    };
    params.Signature = await buildAliyunSignature("POST", params, accessKeySecret);

    const formBody = Object.entries(params)
      .map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
      .join("&");

    console.log("[verify-sms-code] Calling DYPNS CheckSmsVerifyCode for:", phone);

    const apiResp = await fetch("https://dypnsapi.aliyuncs.com/", {
      method: "POST",
      headers: { "Content-Type": "application/x-www-form-urlencoded" },
      body: formBody,
    });
    const apiResult = await apiResp.json();

    console.log("[verify-sms-code] Aliyun response:", JSON.stringify(apiResult));

    if (apiResult.Code !== "OK")
      return new Response(
        JSON.stringify({ error: "验证失败，请重新获取验证码" }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );

    if (apiResult.Model?.VerifyResult !== "PASS") {
      const msg =
        apiResult.Model?.VerifyResult === "UNKNOWN"
          ? "验证码已过期，请重新获取"
          : "验证码错误";
      return new Response(
        JSON.stringify({ error: msg }),
        { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Clean up used codes
    await supabase.from("sms_verification_codes").delete().eq("phone", phone);

    // Create or login user via email alias
    const smsEmail = `${phone}@sms.local`;
    const smsPassword = `sms_${phone}_${Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!.slice(-8)}`;

    const signInClient = createClient(
      Deno.env.get("SUPABASE_URL")!,
      Deno.env.get("SUPABASE_ANON_KEY")!
    );

    // Try sign in first
    const { data: signInData, error: signInError } =
      await signInClient.auth.signInWithPassword({
        email: smsEmail,
        password: smsPassword,
      });

    if (!signInError && signInData.session) {
      await supabase
        .from("profiles")
        .update({ phone })
        .eq("user_id", signInData.user.id);

      console.log("[verify-sms-code] Existing user login:", phone);
      return new Response(
        JSON.stringify({
          success: true,
          session: signInData.session,
          user: signInData.user,
          isNewUser: false,
        }),
        { headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    // Create new user
    const { error: createError } = await supabase.auth.admin.createUser({
      email: smsEmail,
      password: smsPassword,
      email_confirm: true,
      user_metadata: { phone, login_method: "sms" },
    });

    if (createError) {
      console.error("[verify-sms-code] Create user error:", createError);
      return new Response(
        JSON.stringify({ error: "创建用户失败: " + createError.message }),
        { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    const { data: newSignIn, error: newSignInError } =
      await signInClient.auth.signInWithPassword({
        email: smsEmail,
        password: smsPassword,
      });

    if (newSignInError) {
      console.error("[verify-sms-code] New user login error:", newSignInError);
      return new Response(
        JSON.stringify({ error: "登录失败: " + newSignInError.message }),
        { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } }
      );
    }

    if (newSignIn.user) {
      await supabase
        .from("profiles")
        .update({ phone, display_name: phone })
        .eq("user_id", newSignIn.user.id);
    }

    console.log("[verify-sms-code] New user created:", phone);
    return new Response(
      JSON.stringify({
        success: true,
        session: newSignIn.session,
        user: newSignIn.user,
        isNewUser: true,
      }),
      { headers: { ...corsHeaders, "Content-Type": "application/json" } }
    );
  } catch (err) {
    console.error("verify-sms-code error:", err);
    return new Response(JSON.stringify({ error: "服务器错误" }), {
      status: 500,
      headers: { ...corsHeaders, "Content-Type": "application/json" },
    });
  }
});
