// Avria Sign — send envelope (in-house e-signature)
import { createClient } from "https://esm.sh/@supabase/supabase-js@2.45.0";

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

interface Recipient { name: string; email: string }
interface FieldPayload {
  recipient_index: number;
  field_type: "signature" | "date" | "name";
  page_number: number;
  x_ratio: number;
  y_ratio: number;
  width_ratio: number;
  height_ratio: number;
}

function toSmtpSenderConfig(sender: any) {
  const port = Number(sender?.smtp_port ?? 587);
  const isImplicitSslPort = port === 465;
  const isStartTlsPort = port === 587;

  return {
    host: sender.smtp_host,
    port,
    username: sender.smtp_username,
    password: sender.smtp_password,
    use_ssl: isImplicitSslPort ? true : sender.use_ssl ?? false,
    use_tls: isImplicitSslPort ? false : sender.use_tls ?? isStartTlsPort,
    from: sender.sender_name
      ? `${sender.sender_name} <${sender.email_address}>`
      : sender.email_address,
    fromEmail: sender.email_address,
    fromName: sender.sender_name,
    envelopeFrom: sender.smtp_username || sender.email_address,
    signature_html: sender.signature_html || "",
  };
}

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

  try {
    const supabaseUrl = Deno.env.get("SUPABASE_URL")!;
    const serviceKey = Deno.env.get("SUPABASE_SERVICE_ROLE_KEY")!;
    const authHeader = req.headers.get("Authorization") || "";
    const token = authHeader.replace("Bearer ", "");

    const userClient = createClient(supabaseUrl, Deno.env.get("SUPABASE_ANON_KEY")!, {
      global: { headers: { Authorization: authHeader } },
    });
    const { data: userData } = await userClient.auth.getUser(token);
    if (!userData?.user) {
      return new Response(JSON.stringify({ error: "unauthorized" }), { status: 401, headers: { ...corsHeaders, "Content-Type": "application/json" } });
    }

    const admin = createClient(supabaseUrl, serviceKey);
    const body = await req.json();
    const {
      association_id,
      document_name,
      document_url,
      document_base64,
      file_extension = "pdf",
      recipients,
      email_subject,
      email_body,
      fields = [],
    }: {
      association_id?: string;
      document_name: string;
      document_url?: string;
      document_base64?: string;
      file_extension?: string;
      recipients: Recipient[];
      email_subject?: string;
      email_body?: string;
      fields?: FieldPayload[];
    } = body;

    if (!document_name || !recipients?.length) {
      return new Response(JSON.stringify({ error: "missing document_name or recipients" }), { status: 400, headers: { ...corsHeaders, "Content-Type": "application/json" } });
    }

    // 1) Insert envelope
    const { data: env, error: envErr } = await admin.from("signature_envelopes").insert({
      association_id: association_id || null,
      document_name,
      document_url: document_url || "",
      email_subject,
      email_body,
      status: "sent",
      created_by: userData.user.id,
      sent_at: new Date().toISOString(),
    }).select().single();
    if (envErr) throw envErr;

    // 2) If raw upload, store
    let finalDocUrl = document_url || "";
    if (document_base64) {
      const binary = Uint8Array.from(atob(document_base64), c => c.charCodeAt(0));
      const path = `signature-envelopes/${env.id}/original.${file_extension}`;
      const { error: upErr } = await admin.storage.from("files").upload(path, binary, {
        contentType: file_extension === "pdf" ? "application/pdf" : "application/octet-stream",
        upsert: true,
      });
      if (upErr) throw upErr;
      const { data: pub } = admin.storage.from("files").getPublicUrl(path);
      finalDocUrl = pub.publicUrl;
      await admin.from("signature_envelopes").update({ document_url: finalDocUrl }).eq("id", env.id);
    }

    // 3) Insert recipients
    const recipientRows = recipients.map((r, idx) => ({
      envelope_id: env.id,
      name: r.name.trim(),
      email: r.email.trim().toLowerCase(),
      signing_order: idx + 1,
      status: "pending",
    }));
    const { data: insertedRecips, error: rErr } = await admin.from("signature_recipients").insert(recipientRows).select();
    if (rErr) throw rErr;

    // 3b) Insert placed fields, mapping recipient_index -> inserted recipient id
    if (fields.length > 0 && insertedRecips) {
      const fieldRows = fields
        .filter(f => insertedRecips[f.recipient_index])
        .map(f => ({
          envelope_id: env.id,
          recipient_id: insertedRecips[f.recipient_index].id,
          field_type: f.field_type,
          page_number: f.page_number,
          x_ratio: f.x_ratio,
          y_ratio: f.y_ratio,
          width_ratio: f.width_ratio,
          height_ratio: f.height_ratio,
        }));
      if (fieldRows.length > 0) {
        const { error: fErr } = await admin.from("signature_fields").insert(fieldRows);
        if (fErr) console.warn("field insert error:", fErr);
      }
    }

    // 4) Audit
    await admin.from("signature_events").insert({
      envelope_id: env.id,
      event_type: "sent",
      details: { recipient_count: recipients.length, document_name, field_count: fields.length },
    });

    // 5) Default sender
    const { data: defaultSender } = await admin
      .from("email_senders")
      .select("smtp_host, smtp_port, smtp_username, smtp_password, use_tls, use_ssl, email_address, sender_name, signature_html")
      .eq("is_active", true)
      .eq("is_default", true)
      .order("updated_at", { ascending: false })
      .limit(1)
      .maybeSingle();

    const smtpSender = defaultSender ? toSmtpSenderConfig(defaultSender) : null;

    // 6) Email + notifications
    const appOrigin = req.headers.get("origin") || "https://avria.cloud";
    const subject = email_subject || `Please sign: ${document_name}`;

    for (const recip of insertedRecips || []) {
      const signUrl = `${appOrigin}/sign/${recip.signing_token}`;
      const html = `
        <div style="font-family:Arial,sans-serif;max-width:600px;margin:0 auto;padding:20px;">
          <h2 style="color:#1e3a8a;">Signature Requested</h2>
          <p>Hi ${recip.name},</p>
          <p>You have been requested to electronically sign the following document:</p>
          <p style="font-size:16px;font-weight:bold;color:#1e3a8a;">${document_name}</p>
          ${email_body ? `<p style="white-space:pre-wrap;">${email_body}</p>` : ""}
          <p style="margin:30px 0;">
            <a href="${signUrl}" style="background:#1e3a8a;color:#fff;padding:12px 24px;text-decoration:none;border-radius:6px;display:inline-block;">Review &amp; Sign Document</a>
          </p>
          <p style="font-size:12px;color:#666;">Or copy this link into your browser:<br/>${signUrl}</p>
          <hr style="margin-top:30px;border:none;border-top:1px solid #eee;"/>
          <p style="font-size:11px;color:#999;">Avria Sign — Secure Electronic Signatures</p>
        </div>`;

      if (smtpSender) {
        try {
          await admin.functions.invoke("send-smtp-email", {
            body: {
              sender: smtpSender,
              recipient: recip.email,
              subject,
              html,
              body: html,
              fallback_user_id: userData.user.id,
              feature_type: "signature_request",
            },
          });
        } catch (e) {
          console.warn(`SMTP email failed for ${recip.email}:`, e);
        }
      }

      try {
        const { data: existingUser } = await admin
          .from("profiles").select("user_id").ilike("email", recip.email).maybeSingle();
        const targetUserId = existingUser?.user_id || recip.user_id;
        if (targetUserId) {
          await admin.rpc("insert_notification", {
            p_user_id: targetUserId,
            p_type: "signature_request",
            p_title: "Signature requested",
            p_message: `Please sign: ${document_name}`,
            p_related_item_id: env.id,
            p_related_item_type: "signature_envelope",
            p_link: `/sign/${recip.signing_token}`,
          });
        }
      } catch (e) {
        console.warn(`Notification failed for ${recip.email}:`, e);
      }
    }

    return new Response(JSON.stringify({
      envelope_id: env.id,
      recipient_count: insertedRecips?.length || 0,
      field_count: fields.length,
    }), { headers: { ...corsHeaders, "Content-Type": "application/json" } });
  } catch (err: any) {
    console.error("avria-sign-send error:", err);
    return new Response(JSON.stringify({ error: err.message || String(err) }), { status: 500, headers: { ...corsHeaders, "Content-Type": "application/json" } });
  }
});
