"use server";

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

import { logAudit } from "./audit";
import {
  DATABASE_ID,
  TABLES,
  type ClinicPricing,
  type Connection,
} from "./schema";
import { createAdminClient } from "./server";
import {
  requireRole,
  requireTenant,
  requireTenantKind,
} from "./tenant-guard";
import type {
  ClinicPricingActionState,
  ClinicPricingFormState,
} from "./clinic-pricing-types";
import { clinicPricingSchema } from "@/lib/validation/clinic-pricing";

function appwriteError(e: unknown, fallback = "Beklenmeyen bir hata oluştu."): string {
  if (e instanceof AppwriteException) return e.message || fallback;
  return process.env.NODE_ENV !== "production" && e instanceof Error
    ? `${fallback} (${e.message})`
    : fallback;
}

function flattenErrors(err: z.ZodError): Record<string, string> {
  const out: Record<string, string> = {};
  for (const issue of err.issues) {
    const key = issue.path.join(".");
    if (key && !out[key]) out[key] = issue.message;
  }
  return out;
}

function pricingPermissions(labTenantId: string, clinicTenantId: string): string[] {
  return [
    Permission.read(Role.team(labTenantId)),
    Permission.read(Role.team(clinicTenantId)),
    Permission.update(Role.team(labTenantId, "owner")),
    Permission.update(Role.team(labTenantId, "admin")),
    Permission.delete(Role.team(labTenantId, "owner")),
    Permission.delete(Role.team(labTenantId, "admin")),
  ];
}

function pickFields(formData: FormData) {
  return {
    clinicTenantId: String(formData.get("clinicTenantId") ?? "").trim(),
    prostheticType: String(formData.get("prostheticType") ?? "").trim(),
    customUnitPrice: String(formData.get("customUnitPrice") ?? "").trim(),
    discountPercent: String(formData.get("discountPercent") ?? "").trim(),
    currency: String(formData.get("currency") ?? "").trim(),
  };
}

export async function setClinicPricingAction(
  _prev: ClinicPricingFormState,
  formData: FormData,
): Promise<ClinicPricingFormState> {
  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
    requireTenantKind(ctx, ["lab"]);
  } catch {
    return { ok: false, error: "Fiyatlandırma yalnızca laboratuvar hesapları için." };
  }

  const parsed = clinicPricingSchema.safeParse(pickFields(formData));
  if (!parsed.success) {
    return { ok: false, error: "Form geçersiz.", fieldErrors: flattenErrors(parsed.error) };
  }

  const { tablesDB } = createAdminClient();

  // Verify the lab actually has an approved connection with this clinic
  const connRes = await tablesDB.listRows({
    databaseId: DATABASE_ID,
    tableId: TABLES.connections,
    queries: [
      Query.equal("labTenantId", ctx.tenantId),
      Query.equal("clinicTenantId", parsed.data.clinicTenantId),
      Query.equal("status", "approved"),
      Query.limit(1),
    ],
  });
  if (!(connRes.rows[0] as unknown as Connection | undefined)) {
    return {
      ok: false,
      error: "Onaylı bir bağlantınız yok.",
      fieldErrors: { clinicTenantId: "Bağlantı yok." },
    };
  }

  try {
    const existing = await tablesDB.listRows({
      databaseId: DATABASE_ID,
      tableId: TABLES.clinicPricing,
      queries: [
        Query.equal("labTenantId", ctx.tenantId),
        Query.equal("clinicTenantId", parsed.data.clinicTenantId),
        Query.equal("prostheticType", parsed.data.prostheticType),
        Query.limit(1),
      ],
    });
    const row = existing.rows[0] as unknown as ClinicPricing | undefined;

    const payload = {
      labTenantId: ctx.tenantId,
      clinicTenantId: parsed.data.clinicTenantId,
      prostheticType: parsed.data.prostheticType,
      customUnitPrice: parsed.data.customUnitPrice,
      discountPercent: parsed.data.discountPercent,
      currency: parsed.data.currency,
      createdBy: ctx.user.id,
    };

    if (row) {
      await tablesDB.updateRow(DATABASE_ID, TABLES.clinicPricing, row.$id, payload);
      await logAudit({
        tenantId: ctx.tenantId,
        userId: ctx.user.id,
        action: "update",
        entityType: "clinic_pricing",
        entityId: row.$id,
        changes: payload,
      });
    } else {
      const created = await tablesDB.createRow(
        DATABASE_ID,
        TABLES.clinicPricing,
        ID.unique(),
        payload,
        pricingPermissions(ctx.tenantId, parsed.data.clinicTenantId),
      );
      await logAudit({
        tenantId: ctx.tenantId,
        userId: ctx.user.id,
        action: "create",
        entityType: "clinic_pricing",
        entityId: created.$id,
        changes: payload,
      });
    }
  } catch (e) {
    return { ok: false, error: appwriteError(e, "Fiyatlandırma kaydedilemedi.") };
  }

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

export async function clearClinicPricingAction(
  _prev: ClinicPricingActionState,
  formData: FormData,
): Promise<ClinicPricingActionState> {
  const id = String(formData.get("id") ?? "").trim();
  if (!id) return { ok: false, error: "Kayıt bulunamadı." };

  let ctx;
  try {
    ctx = await requireTenant();
    requireRole(ctx, ["owner", "admin"]);
    requireTenantKind(ctx, ["lab"]);
  } catch {
    return { ok: false, error: "Yetkiniz yok." };
  }

  try {
    const { tablesDB } = createAdminClient();
    const row = (await tablesDB.getRow(
      DATABASE_ID,
      TABLES.clinicPricing,
      id,
    )) as unknown as ClinicPricing;
    if (row.labTenantId !== ctx.tenantId) {
      return { ok: false, error: "Yetkiniz yok." };
    }
    await tablesDB.deleteRow(DATABASE_ID, TABLES.clinicPricing, id);
    await logAudit({
      tenantId: ctx.tenantId,
      userId: ctx.user.id,
      action: "delete",
      entityType: "clinic_pricing",
      entityId: id,
    });
  } catch (e) {
    return { ok: false, error: appwriteError(e, "Silinemedi.") };
  }

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