import {
  pgTable,
  text,
  boolean,
  integer,
  numeric,
  timestamp,
  date,
  jsonb,
  index,
  uniqueIndex,
  primaryKey,
} from 'drizzle-orm/pg-core';
import { ports } from './ports';
import { clients } from './clients';

export const berths = pgTable(
  'berths',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    portId: text('port_id')
      .notNull()
      .references(() => ports.id),
    mooringNumber: text('mooring_number').notNull(),
    area: text('area'),
    status: text('status').notNull().default('available'), // available, under_offer, sold
    lengthFt: numeric('length_ft'),
    widthFt: numeric('width_ft'),
    draftFt: numeric('draft_ft'),
    lengthM: numeric('length_m'),
    widthM: numeric('width_m'),
    draftM: numeric('draft_m'),
    widthIsMinimum: boolean('width_is_minimum').default(false),
    nominalBoatSize: text('nominal_boat_size'),
    nominalBoatSizeM: text('nominal_boat_size_m'),
    waterDepth: numeric('water_depth'),
    waterDepthM: numeric('water_depth_m'),
    waterDepthIsMinimum: boolean('water_depth_is_minimum').default(false),
    sidePontoon: text('side_pontoon'),
    powerCapacity: text('power_capacity'),
    voltage: text('voltage'),
    mooringType: text('mooring_type'),
    cleatType: text('cleat_type'),
    cleatCapacity: text('cleat_capacity'),
    bollardType: text('bollard_type'),
    bollardCapacity: text('bollard_capacity'),
    access: text('access'),
    price: numeric('price'),
    priceCurrency: text('price_currency').notNull().default('USD'),
    bowFacing: text('bow_facing'),
    berthApproved: boolean('berth_approved').default(false),
    tenureType: text('tenure_type').notNull().default('permanent'), // permanent, fixed_term
    tenureYears: integer('tenure_years'),
    tenureStartDate: date('tenure_start_date'),
    tenureEndDate: date('tenure_end_date'),
    statusLastChangedBy: text('status_last_changed_by'), // user ID
    statusLastChangedReason: text('status_last_changed_reason'),
    statusLastModified: timestamp('status_last_modified', { withTimezone: true }),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
    updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [
    index('idx_berths_port').on(table.portId),
    index('idx_berths_status').on(table.portId, table.status),
    index('idx_berths_area').on(table.portId, table.area),
    uniqueIndex('idx_berths_mooring').on(table.portId, table.mooringNumber),
  ],
);

export const berthMapData = pgTable(
  'berth_map_data',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    berthId: text('berth_id')
      .notNull()
      .unique()
      .references(() => berths.id, { onDelete: 'cascade' }),
    svgPath: text('svg_path'),
    x: numeric('x'),
    y: numeric('y'),
    transform: text('transform'),
    fontSize: numeric('font_size'),
    extraData: jsonb('extra_data').default({}),
    updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [uniqueIndex('berth_map_data_berth_id_idx').on(table.berthId)],
);

export const berthRecommendations = pgTable(
  'berth_recommendations',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    interestId: text('interest_id').notNull(), // references interests.id
    berthId: text('berth_id')
      .notNull()
      .references(() => berths.id, { onDelete: 'cascade' }),
    matchScore: numeric('match_score'), // 0-100
    matchReasons: jsonb('match_reasons'), // { "dimensional_fit": 95, "power_match": 80, ... }
    source: text('source').notNull().default('ai'), // ai, manual
    createdBy: text('created_by'), // user ID for manual recommendations
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [
    uniqueIndex('berth_rec_interest_berth_idx').on(table.interestId, table.berthId),
    index('idx_br_interest').on(table.interestId),
  ],
);

export const berthWaitingList = pgTable(
  'berth_waiting_list',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    berthId: text('berth_id')
      .notNull()
      .references(() => berths.id, { onDelete: 'cascade' }),
    clientId: text('client_id')
      .notNull()
      .references(() => clients.id, { onDelete: 'cascade' }),
    yachtId: text('yacht_id'), // FK added via relation; nullable (waiting for this yacht)
    position: integer('position').notNull(),
    priority: text('priority').notNull().default('normal'), // normal, high
    notifyPref: text('notify_pref').default('email'), // email, in_app, both
    notes: text('notes'),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [
    uniqueIndex('berth_waiting_list_berth_client_idx').on(table.berthId, table.clientId),
    index('idx_bwl_berth').on(table.berthId, table.position),
  ],
);

export const berthMaintenanceLog = pgTable(
  'berth_maintenance_log',
  {
    id: text('id')
      .primaryKey()
      .$defaultFn(() => crypto.randomUUID()),
    berthId: text('berth_id')
      .notNull()
      .references(() => berths.id, { onDelete: 'cascade' }),
    portId: text('port_id')
      .notNull()
      .references(() => ports.id),
    category: text('category').notNull(), // routine, repair, inspection, upgrade
    description: text('description').notNull(),
    cost: numeric('cost'),
    costCurrency: text('cost_currency').default('USD'),
    responsibleParty: text('responsible_party'),
    performedDate: date('performed_date').notNull(),
    photoFileIds: text('photo_file_ids').array(), // references to files table
    createdBy: text('created_by').notNull(),
    createdAt: timestamp('created_at', { withTimezone: true }).notNull().defaultNow(),
    updatedAt: timestamp('updated_at', { withTimezone: true }).notNull().defaultNow(),
  },
  (table) => [index('idx_bml_berth').on(table.berthId), index('idx_bml_port').on(table.portId)],
);

export const berthTags = pgTable(
  'berth_tags',
  {
    berthId: text('berth_id')
      .notNull()
      .references(() => berths.id, { onDelete: 'cascade' }),
    tagId: text('tag_id').notNull(), // references tags.id
  },
  (table) => [primaryKey({ columns: [table.berthId, table.tagId] })],
);

export type Berth = typeof berths.$inferSelect;
export type NewBerth = typeof berths.$inferInsert;
export type BerthMapData = typeof berthMapData.$inferSelect;
export type NewBerthMapData = typeof berthMapData.$inferInsert;
export type BerthRecommendation = typeof berthRecommendations.$inferSelect;
export type NewBerthRecommendation = typeof berthRecommendations.$inferInsert;
export type BerthWaitingList = typeof berthWaitingList.$inferSelect;
export type NewBerthWaitingList = typeof berthWaitingList.$inferInsert;
export type BerthMaintenanceLog = typeof berthMaintenanceLog.$inferSelect;
export type NewBerthMaintenanceLog = typeof berthMaintenanceLog.$inferInsert;
