/**
 * Water Log. Source: `db/migrations/0001_init.sql` + `0090_water_log_completion.sql`.
 *
 * Six tables, all brand-scoped with RLS:
 *   - water_headgates         — physical gates a measurement is tied to
 *   - water_irrigators        — PIN-authenticated field workers
 *   - water_sessions          — short-lived PIN sessions for irrigators
 *   - water_log_entries       — the actual reading logs
 *   - water_alert_log         — high/low threshold alert history
 *   - water_admin_settings    — per-brand admin PIN + alert config
 *   - water_admin_sessions    — admin sign-in sessions (separate cookie)
 *   - water_audit_log         — who changed what, when
 */
import {
  pgTable,
  uuid,
  text,
  numeric,
  boolean,
  timestamp,
  date,
  jsonb,
  doublePrecision,
  index,
  uniqueIndex,
  integer,
  check,
} from "drizzle-orm/pg-core";
import { brands } from "./brands";
import { adminUsers } from "./brands";

export const waterHeadgates = pgTable(
  "water_headgates",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    brandId: uuid("brand_id")
      .notNull()
      .references(() => brands.id, { onDelete: "cascade" }),
    name: text("name").notNull(),
    /** Per-headgate opaque token used in the QR code. */
    headgateToken: text("headgate_token").notNull().unique(),
    /** Open / Closed / Maintenance. */
    status: text("status").notNull().default("open"),
    /** Display unit: CFS, GPM, Inches, AF/Day, etc. */
    unit: text("unit").notNull().default("CFS"),
    /** Optional max-flow marker in GPM. */
    maxFlowGpm: numeric("max_flow_gpm"),
    /** High-water alert threshold (units match `unit`). */
    highThreshold: numeric("high_threshold"),
    /** Low-water alert threshold (units match `unit`). */
    lowThreshold: numeric("low_threshold"),
    notes: text("notes"),
    active: boolean("active").notNull().default(true),
    lastUsedAt: timestamp("last_used_at", { withTimezone: true }),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
  (t) => ({
    brandIdx: index("water_headgates_brand_idx").on(t.brandId),
    tokenIdx: uniqueIndex("water_headgates_token_idx").on(t.headgateToken),
  }),
);

export const waterIrrigators = pgTable(
  "water_irrigators",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    brandId: uuid("brand_id")
      .notNull()
      .references(() => brands.id, { onDelete: "cascade" }),
    name: text("name").notNull(),
    pinHash: text("pin_hash").notNull(),
    languagePreference: text("language_preference")
      .notNull()
      .default("en"),
    /** "irrigator" submits entries only, "water_admin" can manage the brand. */
    role: text("role").notNull().default("irrigator"),
    phone: text("phone"),
    notes: text("notes"),
    active: boolean("active").notNull().default(true),
    lastUsedAt: timestamp("last_used_at", { withTimezone: true }),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
  (t) => ({
    brandIdx: index("water_irrigators_brand_idx").on(t.brandId),
  }),
);

export const waterSessions = pgTable(
  "water_sessions",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    irrigatorId: uuid("irrigator_id")
      .notNull()
      .references(() => waterIrrigators.id, { onDelete: "cascade" }),
    expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
);

export const waterLogEntries = pgTable(
  "water_log_entries",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    brandId: uuid("brand_id")
      .notNull()
      .references(() => brands.id, { onDelete: "cascade" }),
    headgateId: uuid("headgate_id")
      .notNull()
      .references(() => waterHeadgates.id, { onDelete: "cascade" }),
    irrigatorId: uuid("irrigator_id")
      .notNull()
      .references(() => waterIrrigators.id, { onDelete: "cascade" }),
    /** Raw measurement value, in the entry's `unit`. */
    measurement: numeric("measurement").notNull(),
    unit: text("unit").notNull(),
    /** "manual" | "meter" | "estimate" | "qr" */
    method: text("method").notNull().default("manual"),
    /** Optional auto-computed total (in gallons) when CFS × duration is known. */
    totalGallons: numeric("total_gallons"),
    notes: text("notes"),
    submittedVia: text("submitted_via").notNull().default("app"),
    photoUrl: text("photo_url"),
    latitude: doublePrecision("latitude"),
    longitude: doublePrecision("longitude"),
    /** Date-only mirror of loggedAt for fast grouping / dashboard queries. */
    loggedDate: date("logged_date"),
    loggedAt: timestamp("logged_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
    loggedBy: uuid("logged_by").references(() => adminUsers.id),
  },
  (t) => ({
    brandIdx: index("water_log_entries_brand_idx").on(t.brandId),
    headgateIdx: index("water_log_entries_headgate_idx").on(t.headgateId),
    brandDateIdx: index("water_log_entries_brand_date_idx").on(
      t.brandId,
      t.loggedDate,
    ),
    irrigatorIdx: index("water_log_entries_irrigator_idx").on(
      t.irrigatorId,
      t.loggedAt,
    ),
  }),
);

export const waterAlertLog = pgTable(
  "water_alert_log",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    brandId: uuid("brand_id")
      .notNull()
      .references(() => brands.id, { onDelete: "cascade" }),
    alertType: text("alert_type").notNull(),
    headgateId: uuid("headgate_id").references(() => waterHeadgates.id, {
      onDelete: "set null",
    }),
    message: text("message").notNull(),
    sentTo: text("sent_to"),
    sentAt: timestamp("sent_at", { withTimezone: true }),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
);

export const waterAdminSettings = pgTable("water_admin_settings", {
  brandId: uuid("brand_id")
    .primaryKey()
    .references(() => brands.id, { onDelete: "cascade" }),
  /** Hashed admin PIN (scrypt $ N$r$p$salt$hash format). */
  pinHash: text("pin_hash"),
  enabled: boolean("enabled").notNull().default(true),
  sessionDurationHours: integer("session_duration_hours")
    .notNull()
    .default(4),
  canEditEntries: boolean("can_edit_entries").notNull().default(true),
  canDeleteEntries: boolean("can_delete_entries").notNull().default(true),
  canExportCsv: boolean("can_export_csv").notNull().default(true),
  alertPhone: text("alert_phone"),
  alertsEnabled: boolean("alerts_enabled").notNull().default(false),
  updatedAt: timestamp("updated_at", { withTimezone: true })
    .notNull()
    .defaultNow(),
  updatedBy: uuid("updated_by").references(() => adminUsers.id),
});

export const waterAdminSessions = pgTable(
  "water_admin_sessions",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    brandId: uuid("brand_id")
      .notNull()
      .references(() => brands.id, { onDelete: "cascade" }),
    adminUserId: uuid("admin_user_id")
      .notNull()
      .references(() => adminUsers.id, { onDelete: "cascade" }),
    pinHashUsed: text("pin_hash_used").notNull(),
    expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
  (t) => ({
    adminIdx: index("water_admin_sessions_admin_idx").on(
      t.adminUserId,
      t.expiresAt,
    ),
  }),
);

export const waterAuditLog = pgTable(
  "water_audit_log",
  {
    id: uuid("id").primaryKey().defaultRandom(),
    brandId: uuid("brand_id")
      .notNull()
      .references(() => brands.id, { onDelete: "cascade" }),
    actorId: uuid("actor_id").references(() => adminUsers.id),
    actorLabel: text("actor_label").notNull(),
    action: text("action").notNull(),
    entityType: text("entity_type").notNull(),
    entityId: uuid("entity_id"),
    details: jsonb("details"),
    createdAt: timestamp("created_at", { withTimezone: true })
      .notNull()
      .defaultNow(),
  },
  (t) => ({
    brandRecentIdx: index("water_audit_log_brand_recent_idx").on(
      t.brandId,
      t.createdAt,
    ),
  }),
);

// ── Inferred types (used by every action and client component) ────────────

export type WaterHeadgate = typeof waterHeadgates.$inferSelect;
export type WaterHeadgateInsert = typeof waterHeadgates.$inferInsert;

export type WaterIrrigator = typeof waterIrrigators.$inferSelect;
export type WaterIrrigatorInsert = typeof waterIrrigators.$inferInsert;

export type WaterSession = typeof waterSessions.$inferSelect;
export type WaterLogEntry = typeof waterLogEntries.$inferSelect;
export type WaterLogEntryInsert = typeof waterLogEntries.$inferInsert;

export type WaterAlertLog = typeof waterAlertLog.$inferSelect;
export type WaterAdminSettings = typeof waterAdminSettings.$inferSelect;
export type WaterAdminSession = typeof waterAdminSessions.$inferSelect;
export type WaterAuditLog = typeof waterAuditLog.$inferSelect;
