"use server";

import { ID, Permission, Role, Query } from "node-appwrite";
import { revalidatePath } from "next/cache";

import { dealSchema } from "@/lib/validation/deals";
import { DATABASE_ID, TABLES, type DealStatus, type Customer } from "./schema";
import { createAdminClient } from "./server";
import { requireTenant, requireRole } from "@/lib/appwrite/tenant-guard";

async function resolveCustomerName(tablesDB: ReturnType<typeof createAdminClient>["tablesDB"], customerId?: string): Promise<string | undefined> {
  if (!customerId) return undefined;
  try {
    const row = await tablesDB.getRow(DATABASE_ID, TABLES.customers, customerId);
    return (row as unknown as Customer).name;
  } catch {
    return undefined;
  }
}

type ActionState = { ok: boolean; error?: string; fieldErrors?: Record<string, string[]> };

export async function createDealAction(
  _prev: ActionState,
  formData: FormData,
): Promise<ActionState> {
  const ctx = await requireTenant();
  const raw = Object.fromEntries(formData.entries());
  const parsed = dealSchema.safeParse(raw);
  if (!parsed.success) {
    return { ok: false, fieldErrors: parsed.error.flatten().fieldErrors };
  }

  const { tablesDB } = createAdminClient();
  const data = parsed.data;
  const customerName = await resolveCustomerName(tablesDB, data.customerId);

  try {
    await tablesDB.createRow(
      DATABASE_ID,
      TABLES.deals,
      ID.unique(),
      {
        tenantId: ctx.tenantId,
        propertyId: data.propertyId,
        customerId: data.customerId,
        propertyTitle: data.propertyTitle,
        customerName,
        type: data.type,
        status: "bekleyen",
        salePrice: data.salePrice,
        commissionRate: data.commissionRate,
        commissionAmount: data.commissionAmount,
        officeSharePercent: data.officeSharePercent,
        agentSharePercent: data.agentSharePercent,
        referralName: data.referralName || null,
        referralPhone: data.referralPhone || null,
        referralPercent: data.referralPercent ?? null,
        agentId: ctx.user.id,
        agentName: ctx.user.name,
        closingDate: data.closingDate,
        notes: data.notes,
        createdBy: ctx.user.id,
      },
      [
        Permission.read(Role.team(ctx.tenantId)),
        Permission.update(Role.team(ctx.tenantId)),
        Permission.delete(Role.team(ctx.tenantId, "owner")),
        Permission.delete(Role.team(ctx.tenantId, "admin")),
      ],
    );
  } catch {
    return { ok: false, error: "İşlem kaydedilemedi." };
  }

  revalidatePath("/finance");
  return { ok: true };
}

export async function updateDealAction(
  id: string,
  _prev: ActionState,
  formData: FormData,
): Promise<ActionState> {
  const ctx = await requireTenant();
  const raw = Object.fromEntries(formData.entries());
  const parsed = dealSchema.safeParse(raw);
  if (!parsed.success) {
    return { ok: false, fieldErrors: parsed.error.flatten().fieldErrors };
  }

  const { tablesDB } = createAdminClient();
  const data = parsed.data;
  const customerName = await resolveCustomerName(tablesDB, data.customerId);

  // Agents can only edit their own deals; owners/admins can edit all
  if (ctx.role === "member") {
    const existing = await tablesDB.getRow(DATABASE_ID, TABLES.deals, id);
    if ((existing as unknown as { agentId: string }).agentId !== ctx.user.id) {
      return { ok: false, error: "Bu işlemi düzenleme yetkiniz yok." };
    }
  }

  try {
    await tablesDB.updateRow(DATABASE_ID, TABLES.deals, id, {
      propertyId: data.propertyId,
      customerId: data.customerId,
      propertyTitle: data.propertyTitle,
      customerName,
      type: data.type,
      salePrice: data.salePrice,
      commissionRate: data.commissionRate,
      commissionAmount: data.commissionAmount,
      officeSharePercent: data.officeSharePercent,
      agentSharePercent: data.agentSharePercent,
      referralName: data.referralName || null,
      referralPhone: data.referralPhone || null,
      referralPercent: data.referralPercent ?? null,
      closingDate: data.closingDate,
      notes: data.notes,
    });
  } catch {
    return { ok: false, error: "İşlem güncellenemedi." };
  }

  revalidatePath("/finance");
  return { ok: true };
}

export async function updateDealStatusAction(
  id: string,
  status: DealStatus,
): Promise<ActionState> {
  const ctx = await requireTenant();
  requireRole(ctx, ["owner", "admin"]);

  const { tablesDB } = createAdminClient();

  try {
    await tablesDB.updateRow(DATABASE_ID, TABLES.deals, id, { status });
  } catch {
    return { ok: false, error: "Durum güncellenemedi." };
  }

  revalidatePath("/finance");
  return { ok: true };
}

export async function deleteDealAction(id: string): Promise<ActionState> {
  const ctx = await requireTenant();
  requireRole(ctx, ["owner", "admin"]);

  const { tablesDB } = createAdminClient();

  try {
    await tablesDB.deleteRow(DATABASE_ID, TABLES.deals, id);
  } catch {
    return { ok: false, error: "İşlem silinemedi." };
  }

  revalidatePath("/finance");
  return { ok: true };
}

export async function getDealsAction() {
  const ctx = await requireTenant();
  const { tablesDB } = createAdminClient();

  const queries = [
    Query.equal("tenantId", ctx.tenantId),
    Query.orderDesc("$createdAt"),
    Query.limit(200),
  ];

  // Members only see their own deals
  if (ctx.role === "member") {
    queries.push(Query.equal("agentId", ctx.user.id));
  }

  const result = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.deals,
    queries,
  });

  return result.rows;
}
