import { cookies } from "next/headers";
import { NextResponse } from "next/server";
import { createAdminClient } from "@/lib/supabase-admin";
import {
  normalizeClientAddressInput,
  isClientAddressComplete,
  type ClientAddressInput,
} from "@/lib/client-portal-addresses";

type SessionPayload = {
  client?: {
    id?: string | null;
  } | null;
};

type AddressBody = {
  slug?: string;
  id?: string;
  label?: string | null;
  recipient_name?: string | null;
  phone?: string | null;
  zip?: string | null;
  street?: string | null;
  number?: string | null;
  complement?: string | null;
  neighborhood?: string | null;
  city?: string | null;
  state?: string | null;
  reference?: string | null;
  is_default?: boolean | null;
};

function normalizeText(value: unknown) {
  return String(value || "").trim();
}

async function resolveSession(slug: string, token: string) {
  const admin = createAdminClient();
  const sessionResult = await admin.rpc("client_portal_get_session", {
    p_slug: slug,
    p_session_token: token,
  });
  const sessionPayload = (sessionResult.data || null) as SessionPayload | null;
  if (sessionResult.error || !sessionPayload?.client?.id) {
    return {
      admin,
      clientId: null as string | null,
    };
  }
  const { data: profile } = await admin
    .from("profiles")
    .select("id")
    .eq("slug", slug)
    .maybeSingle();
  if (!profile?.id) {
    return {
      admin,
      clientId: null as string | null,
    };
  }
  return {
    admin,
    profileId: String(profile.id),
    clientId: String(sessionPayload.client.id),
  };
}

export async function GET(request: Request) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get("ks_client_portal")?.value || "";
    if (!token) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const { searchParams } = new URL(request.url);
    const slug = normalizeText(searchParams.get("slug"));
    if (!slug) {
      return NextResponse.json({ error: "Loja inválida." }, { status: 400 });
    }

    const resolved = await resolveSession(slug, token);
    if (!resolved.clientId || !resolved.profileId) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const { data, error } = await resolved.admin
      .from("client_addresses")
      .select("id,label,recipient_name,phone,zip,street,number,complement,neighborhood,city,state,reference,is_default,created_at,updated_at")
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null)
      .order("is_default", { ascending: false })
      .order("updated_at", { ascending: false });

    if (error) {
      return NextResponse.json({ error: "Não foi possível carregar os endereços." }, { status: 500 });
    }

    return NextResponse.json({
      ok: true,
      addresses: Array.isArray(data) ? data : [],
    });
  } catch {
    return NextResponse.json({ error: "Não foi possível carregar os endereços." }, { status: 500 });
  }
}

export async function POST(request: Request) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get("ks_client_portal")?.value || "";
    if (!token) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const body = (await request.json().catch(() => null)) as AddressBody | null;
    const slug = normalizeText(body?.slug);
    if (!slug) {
      return NextResponse.json({ error: "Loja inválida." }, { status: 400 });
    }

    const resolved = await resolveSession(slug, token);
    if (!resolved.clientId || !resolved.profileId) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const normalized = normalizeClientAddressInput(body as ClientAddressInput);
    if (!isClientAddressComplete(normalized)) {
      return NextResponse.json({ error: "Preencha os campos obrigatórios do endereço." }, { status: 400 });
    }

    const { count } = await resolved.admin
      .from("client_addresses")
      .select("id", { count: "exact", head: true })
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null);

    const shouldBeDefault = Boolean(normalized.is_default) || Number(count || 0) === 0;

    if (shouldBeDefault) {
      await resolved.admin
        .from("client_addresses")
        .update({ is_default: false, updated_at: new Date().toISOString() })
        .eq("client_id", resolved.clientId)
        .eq("user_id", resolved.profileId)
        .is("deleted_at", null);
    }

    const payload = {
      user_id: resolved.profileId,
      client_id: resolved.clientId,
      label: normalized.label || "Endereco",
      recipient_name: normalized.recipient_name || null,
      phone: normalized.phone || null,
      zip: normalized.zip || null,
      street: normalized.street || null,
      number: normalized.number || null,
      complement: normalized.complement || null,
      neighborhood: normalized.neighborhood || null,
      city: normalized.city || null,
      state: normalized.state || null,
      reference: normalized.reference || null,
      is_default: shouldBeDefault,
    };

    const { data: created, error: createError } = await resolved.admin
      .from("client_addresses")
      .insert(payload)
      .select("id,label,recipient_name,phone,zip,street,number,complement,neighborhood,city,state,reference,is_default,created_at,updated_at")
      .single();

    if (createError || !created?.id) {
      return NextResponse.json({ error: "Não foi possível cadastrar o endereço." }, { status: 400 });
    }

    if (created.is_default) {
      await resolved.admin
        .from("clients")
        .update({
          address_zip: created.zip || null,
          address_street: created.street || null,
          address_number: created.number || null,
          address_complement: created.complement || null,
          address_neighborhood: created.neighborhood || null,
          address_city: created.city || null,
          address_state: created.state || null,
          updated_at: new Date().toISOString(),
        })
        .eq("id", resolved.clientId)
        .eq("user_id", resolved.profileId);
    }

    return NextResponse.json({
      ok: true,
      address: created,
    });
  } catch {
    return NextResponse.json({ error: "Não foi possível cadastrar o endereço." }, { status: 500 });
  }
}

export async function PATCH(request: Request) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get("ks_client_portal")?.value || "";
    if (!token) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const body = (await request.json().catch(() => null)) as AddressBody | null;
    const slug = normalizeText(body?.slug);
    const addressId = normalizeText(body?.id);
    if (!slug || !addressId) {
      return NextResponse.json({ error: "Dados inválidos." }, { status: 400 });
    }

    const resolved = await resolveSession(slug, token);
    if (!resolved.clientId || !resolved.profileId) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const normalized = normalizeClientAddressInput(body as ClientAddressInput);
    if (!isClientAddressComplete(normalized)) {
      return NextResponse.json({ error: "Preencha os campos obrigatórios do endereço." }, { status: 400 });
    }

    const { data: existing } = await resolved.admin
      .from("client_addresses")
      .select("id,is_default")
      .eq("id", addressId)
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null)
      .maybeSingle();

    if (!existing?.id) {
      return NextResponse.json({ error: "Endereço não encontrado." }, { status: 404 });
    }

    const shouldBeDefault = Boolean(normalized.is_default) || Boolean(existing.is_default);
    if (shouldBeDefault) {
      await resolved.admin
        .from("client_addresses")
        .update({ is_default: false, updated_at: new Date().toISOString() })
        .eq("client_id", resolved.clientId)
        .eq("user_id", resolved.profileId)
        .is("deleted_at", null);
    }

    const { data: updated, error: updateError } = await resolved.admin
      .from("client_addresses")
      .update({
        label: normalized.label || "Endereco",
        recipient_name: normalized.recipient_name || null,
        phone: normalized.phone || null,
        zip: normalized.zip || null,
        street: normalized.street || null,
        number: normalized.number || null,
        complement: normalized.complement || null,
        neighborhood: normalized.neighborhood || null,
        city: normalized.city || null,
        state: normalized.state || null,
        reference: normalized.reference || null,
        is_default: shouldBeDefault,
        updated_at: new Date().toISOString(),
      })
      .eq("id", addressId)
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null)
      .select("id,label,recipient_name,phone,zip,street,number,complement,neighborhood,city,state,reference,is_default,created_at,updated_at")
      .single();

    if (updateError || !updated?.id) {
      return NextResponse.json({ error: "Não foi possível atualizar o endereço." }, { status: 400 });
    }

    if (updated.is_default) {
      await resolved.admin
        .from("clients")
        .update({
          address_zip: updated.zip || null,
          address_street: updated.street || null,
          address_number: updated.number || null,
          address_complement: updated.complement || null,
          address_neighborhood: updated.neighborhood || null,
          address_city: updated.city || null,
          address_state: updated.state || null,
          updated_at: new Date().toISOString(),
        })
        .eq("id", resolved.clientId)
        .eq("user_id", resolved.profileId);
    }

    return NextResponse.json({
      ok: true,
      address: updated,
    });
  } catch {
    return NextResponse.json({ error: "Não foi possível atualizar o endereço." }, { status: 500 });
  }
}

export async function DELETE(request: Request) {
  try {
    const cookieStore = await cookies();
    const token = cookieStore.get("ks_client_portal")?.value || "";
    if (!token) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const { searchParams } = new URL(request.url);
    const slug = normalizeText(searchParams.get("slug"));
    const addressId = normalizeText(searchParams.get("id"));
    if (!slug || !addressId) {
      return NextResponse.json({ error: "Dados inválidos." }, { status: 400 });
    }

    const resolved = await resolveSession(slug, token);
    if (!resolved.clientId || !resolved.profileId) {
      return NextResponse.json({ error: "Sessão inválida." }, { status: 401 });
    }

    const { data: existing } = await resolved.admin
      .from("client_addresses")
      .select("id,is_default")
      .eq("id", addressId)
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null)
      .maybeSingle();

    if (!existing?.id) {
      return NextResponse.json({ error: "Endereço não encontrado." }, { status: 404 });
    }

    const { count } = await resolved.admin
      .from("client_addresses")
      .select("id", { count: "exact", head: true })
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null);

    if (Number(count || 0) <= 1) {
      return NextResponse.json({ error: "Mantenha pelo menos um endereço cadastrado." }, { status: 400 });
    }

    await resolved.admin
      .from("client_addresses")
      .update({ deleted_at: new Date().toISOString(), is_default: false, updated_at: new Date().toISOString() })
      .eq("id", addressId)
      .eq("client_id", resolved.clientId)
      .eq("user_id", resolved.profileId)
      .is("deleted_at", null);

    if (existing.is_default) {
      const { data: nextDefault } = await resolved.admin
        .from("client_addresses")
        .select("id,zip,street,number,complement,neighborhood,city,state")
        .eq("client_id", resolved.clientId)
        .eq("user_id", resolved.profileId)
        .is("deleted_at", null)
        .order("updated_at", { ascending: false })
        .limit(1)
        .maybeSingle();

      if (nextDefault?.id) {
        await resolved.admin
          .from("client_addresses")
          .update({ is_default: true, updated_at: new Date().toISOString() })
          .eq("id", nextDefault.id)
          .eq("client_id", resolved.clientId)
          .eq("user_id", resolved.profileId)
          .is("deleted_at", null);

        await resolved.admin
          .from("clients")
          .update({
            address_zip: nextDefault.zip || null,
            address_street: nextDefault.street || null,
            address_number: nextDefault.number || null,
            address_complement: nextDefault.complement || null,
            address_neighborhood: nextDefault.neighborhood || null,
            address_city: nextDefault.city || null,
            address_state: nextDefault.state || null,
            updated_at: new Date().toISOString(),
          })
          .eq("id", resolved.clientId)
          .eq("user_id", resolved.profileId);
      }
    }

    return NextResponse.json({ ok: true });
  } catch {
    return NextResponse.json({ error: "Não foi possível remover o endereço." }, { status: 500 });
  }
}
