import mongoose, { Schema, Document } from 'mongoose';

// ============================================
// INTERFACES
// ============================================

export interface IPump extends Document {
  pumpCode: string;
  location: string;
  pumpType: 'SURFACE' | 'ISLAND';
  fuelTypes: string[];
  installationDate: Date;
  lastMaintenance?: Date;
  cumulativeCounter: number;
  active: boolean;
}

export interface ITank extends Document {
  tankCode: string;
  fuelType: string;
  capacityLiters: number;
  minLevelLiters: number;
  maxLevelLiters: number;
  location: string;
  installationDate: Date;
  active: boolean;
}

export interface IProduct extends Document {
  productCode: string;
  productName: string;
  category: string;
  subCategory?: string;
  description?: string;
  fuelType?: string;
  unit: string;
  purchasePrice?: number;
  salePrice?: number;
  baseCost?: number;
  currentStock?: number;
  minStock?: number;
  barcode?: string;
  imageUrl?: string;
  supplierId?: mongoose.Types.ObjectId;
  active: boolean;
}

export interface IPumpTransaction extends Document {
  txDatetime: Date;
  pumpId: mongoose.Types.ObjectId;
  productId: mongoose.Types.ObjectId;
  fuelType: string;
  counterStart: number;
  counterEnd: number;
  liters: number;
  unitPrice: number;
  totalAmount: number;
  paymentMethod: 'CASH' | 'CARD' | 'MOBILE' | 'FLEET_CARD';
  operatorId?: mongoose.Types.ObjectId;
  customerId?: mongoose.Types.ObjectId;
  loyaltyCardId?: string;
  shift: 'MORNING' | 'AFTERNOON' | 'NIGHT';
}

export interface ITankReading extends Document {
  readingDatetime: Date;
  tankId: mongoose.Types.ObjectId;
  levelLiters: number;
  temperature?: number;
  density?: number;
  readingType: 'AUTO' | 'MANUAL' | 'POST_DELIVERY';
  deliveryId?: mongoose.Types.ObjectId;
}

export interface IDelivery extends Document {
  deliveryDatetime: Date;
  tankId: mongoose.Types.ObjectId;
  fuelType: string;
  volumeDelivered: number;
  supplierId?: mongoose.Types.ObjectId;
  deliveryNote: string;
  unitCost: number;
  totalCost: number;
  temperature?: number;
  driverName?: string;
  truckPlate?: string;
  validatedBy?: mongoose.Types.ObjectId;
}

export interface IPurchaseOrder extends Document {
  orderNumber: string;
  orderDate: Date;
  supplierId: mongoose.Types.ObjectId;
  deliveryDate?: Date;
  totalAmount: number;
  status: 'PENDING' | 'RECEIVED' | 'PARTIAL' | 'CANCELLED';
  notes?: string;
  items: Array<{
    productId: mongoose.Types.ObjectId;
    productCode: string;
    productName: string;
    quantity: number;
    unitPrice: number;
    totalPrice: number;
  }>;
  receivedBy?: mongoose.Types.ObjectId;
  validatedBy?: mongoose.Types.ObjectId;
}

export interface IPOSTransaction extends Document {
  txDatetime: Date;
  totalAmount: number;
  paymentMethod: 'CASH' | 'CARD' | 'MOBILE';
  employeeId?: mongoose.Types.ObjectId;
  customerId?: mongoose.Types.ObjectId;
  loyaltyCardId?: string;
  shift: 'MORNING' | 'AFTERNOON' | 'NIGHT';
  items: Array<{
    productId: mongoose.Types.ObjectId;
    quantity: number;
    unitPrice: number;
    lineAmount: number;
    discountAmount: number;
  }>;
}

export interface IEmployee extends Document {
  employeeCode: string;
  firstName: string;
  lastName: string;
  role: 'MANAGER' | 'CASHIER' | 'OPERATOR' | 'MAINTENANCE';
  hireDate: Date;
  active: boolean;
}

export interface ICustomer extends Document {
  customerCode?: string;
  loyaltyCardId: string;
  firstName?: string;
  lastName?: string;
  email?: string;
  phone?: string;
  registrationDate: Date;
  segment: 'VIP' | 'REGULAR' | 'OCCASIONAL';
  totalPoints: number;
  active: boolean;
}

export interface ISupplier extends Document {
  supplierCode: string;
  supplierName: string;
  category: 'FUEL' | 'LUBRICANTS' | 'FILTERS' | 'PARTS' | 'FOOD' | 'SERVICES' | 'OTHER';
  contactPerson?: string;
  phone?: string;
  email?: string;
  address?: string;
  city?: string;
  postalCode?: string;
  taxId?: string;
  paymentTerms?: string;
  active: boolean;
}

// ============================================
// SCHEMAS
// ============================================

const PumpSchema = new Schema<IPump>({
  pumpCode: { type: String, required: true, unique: true },
  location: { type: String, required: true },
  pumpType: { type: String, enum: ['SURFACE', 'ISLAND'], required: true },
  fuelTypes: [{ type: String }],
  installationDate: { type: Date, required: true },
  lastMaintenance: { type: Date },
  cumulativeCounter: { type: Number, default: 0 },
  active: { type: Boolean, default: true },
}, { timestamps: true });

const TankSchema = new Schema<ITank>({
  tankCode: { type: String, required: true, unique: true },
  fuelType: { type: String, required: true },
  capacityLiters: { type: Number, required: true },
  minLevelLiters: { type: Number, required: true },
  maxLevelLiters: { type: Number, required: true },
  location: { type: String, required: true },
  installationDate: { type: Date, required: true },
  active: { type: Boolean, default: true },
}, { timestamps: true });

const ProductSchema = new Schema<IProduct>({
  productCode: { type: String, required: true, unique: true },
  productName: { type: String, required: true },
  category: { type: String, required: true },
  subCategory: { type: String },
  description: { type: String },
  fuelType: { type: String },
  unit: { type: String, required: true },
  purchasePrice: { type: Number },
  salePrice: { type: Number },
  baseCost: { type: Number },
  currentStock: { type: Number, default: 0 },
  minStock: { type: Number, default: 0 },
  barcode: { type: String },
  imageUrl: { type: String },
  supplierId: { type: Schema.Types.ObjectId, ref: 'Supplier' },
  active: { type: Boolean, default: true },
}, { timestamps: true });

const PumpTransactionSchema = new Schema<IPumpTransaction>({
  txDatetime: { type: Date, required: true, index: true },
  pumpId: { type: Schema.Types.ObjectId, ref: 'Pump', required: true },
  productId: { type: Schema.Types.ObjectId, ref: 'Product', required: true },
  fuelType: { type: String, required: true, index: true },
  counterStart: { type: Number, required: true },
  counterEnd: { type: Number, required: true },
  liters: { type: Number, required: true },
  unitPrice: { type: Number, required: true },
  totalAmount: { type: Number, required: true },
  paymentMethod: { type: String, enum: ['CASH', 'CARD', 'MOBILE', 'FLEET_CARD'], required: true },
  operatorId: { type: Schema.Types.ObjectId, ref: 'Employee' },
  customerId: { type: Schema.Types.ObjectId, ref: 'Customer' },
  loyaltyCardId: { type: String },
  shift: { type: String, enum: ['MORNING', 'AFTERNOON', 'NIGHT'], required: true },
}, { timestamps: true });

const TankReadingSchema = new Schema<ITankReading>({
  readingDatetime: { type: Date, required: true, index: true },
  tankId: { type: Schema.Types.ObjectId, ref: 'Tank', required: true },
  levelLiters: { type: Number, required: true },
  temperature: { type: Number },
  density: { type: Number },
  readingType: { type: String, enum: ['AUTO', 'MANUAL', 'POST_DELIVERY'], default: 'AUTO' },
  deliveryId: { type: Schema.Types.ObjectId, ref: 'Delivery' },
}, { timestamps: true });

const DeliverySchema = new Schema<IDelivery>({
  deliveryDatetime: { type: Date, required: true, index: true },
  tankId: { type: Schema.Types.ObjectId, ref: 'Tank', required: true },
  fuelType: { type: String, required: true },
  volumeDelivered: { type: Number, required: true },
  supplierId: { type: Schema.Types.ObjectId, ref: 'Supplier' },
  deliveryNote: { type: String, required: true },
  unitCost: { type: Number, required: true },
  totalCost: { type: Number, required: true },
  temperature: { type: Number },
  driverName: { type: String },
  truckPlate: { type: String },
  validatedBy: { type: Schema.Types.ObjectId, ref: 'Employee' },
}, { timestamps: true });

const PurchaseOrderSchema = new Schema<IPurchaseOrder>({
  orderNumber: { type: String, required: true, unique: true },
  orderDate: { type: Date, required: true, index: true },
  supplierId: { type: Schema.Types.ObjectId, ref: 'Supplier', required: true },
  deliveryDate: { type: Date },
  totalAmount: { type: Number, required: true },
  status: { type: String, enum: ['PENDING', 'RECEIVED', 'PARTIAL', 'CANCELLED'], default: 'PENDING' },
  notes: { type: String },
  items: [{
    productId: { type: Schema.Types.ObjectId, ref: 'Product', required: true },
    productCode: { type: String, required: true },
    productName: { type: String, required: true },
    quantity: { type: Number, required: true },
    unitPrice: { type: Number, required: true },
    totalPrice: { type: Number, required: true },
  }],
  receivedBy: { type: Schema.Types.ObjectId, ref: 'Employee' },
  validatedBy: { type: Schema.Types.ObjectId, ref: 'Employee' },
}, { timestamps: true });

const POSTransactionSchema = new Schema<IPOSTransaction>({
  txDatetime: { type: Date, required: true, index: true },
  totalAmount: { type: Number, required: true },
  paymentMethod: { type: String, enum: ['CASH', 'CARD', 'MOBILE'], required: true },
  employeeId: { type: Schema.Types.ObjectId, ref: 'Employee' },
  customerId: { type: Schema.Types.ObjectId, ref: 'Customer' },
  loyaltyCardId: { type: String },
  shift: { type: String, enum: ['MORNING', 'AFTERNOON', 'NIGHT'], required: true },
  items: [{
    productId: { type: Schema.Types.ObjectId, ref: 'Product', required: true },
    quantity: { type: Number, required: true },
    unitPrice: { type: Number, required: true },
    lineAmount: { type: Number, required: true },
    discountAmount: { type: Number, default: 0 },
  }],
}, { timestamps: true });

const EmployeeSchema = new Schema<IEmployee>({
  employeeCode: { type: String, required: true, unique: true },
  firstName: { type: String, required: true },
  lastName: { type: String, required: true },
  role: { type: String, enum: ['MANAGER', 'CASHIER', 'OPERATOR', 'MAINTENANCE'], required: true },
  hireDate: { type: Date, required: true },
  active: { type: Boolean, default: true },
}, { timestamps: true });

const CustomerSchema = new Schema<ICustomer>({
  customerCode: { type: String, unique: true, sparse: true },
  loyaltyCardId: { type: String, required: true, unique: true },
  firstName: { type: String },
  lastName: { type: String },
  email: { type: String },
  phone: { type: String },
  registrationDate: { type: Date, required: true },
  segment: { type: String, enum: ['VIP', 'REGULAR', 'OCCASIONAL'], default: 'REGULAR' },
  totalPoints: { type: Number, default: 0 },
  active: { type: Boolean, default: true },
}, { timestamps: true });

const SupplierSchema = new Schema<ISupplier>({
  supplierCode: { type: String, required: true, unique: true },
  supplierName: { type: String, required: true },
  category: { type: String, enum: ['FUEL', 'LUBRICANTS', 'FILTERS', 'PARTS', 'FOOD', 'SERVICES', 'OTHER'], required: true },
  contactPerson: { type: String },
  phone: { type: String },
  email: { type: String },
  address: { type: String },
  city: { type: String },
  postalCode: { type: String },
  taxId: { type: String },
  paymentTerms: { type: String },
  active: { type: Boolean, default: true },
}, { timestamps: true });

// ============================================
// INDEXES
// ============================================

PumpTransactionSchema.index({ txDatetime: 1, fuelType: 1 });
PumpTransactionSchema.index({ txDatetime: 1, pumpId: 1 });
TankReadingSchema.index({ readingDatetime: 1, tankId: 1 });
DeliverySchema.index({ deliveryDatetime: 1, tankId: 1 });
POSTransactionSchema.index({ txDatetime: 1 });
PurchaseOrderSchema.index({ orderDate: 1, supplierId: 1 });
PurchaseOrderSchema.index({ orderNumber: 1 });

// ============================================
// EXPORTS
// ============================================

export const Pump = mongoose.models.Pump || mongoose.model<IPump>('Pump', PumpSchema);
export const Tank = mongoose.models.Tank || mongoose.model<ITank>('Tank', TankSchema);
export const Product = mongoose.models.Product || mongoose.model<IProduct>('Product', ProductSchema);
export const PumpTransaction = mongoose.models.PumpTransaction || mongoose.model<IPumpTransaction>('PumpTransaction', PumpTransactionSchema);
export const TankReading = mongoose.models.TankReading || mongoose.model<ITankReading>('TankReading', TankReadingSchema);
export const Delivery = mongoose.models.Delivery || mongoose.model<IDelivery>('Delivery', DeliverySchema);
export const POSTransaction = mongoose.models.POSTransaction || mongoose.model<IPOSTransaction>('POSTransaction', POSTransactionSchema);
export const Employee = mongoose.models.Employee || mongoose.model<IEmployee>('Employee', EmployeeSchema);
export const Customer = mongoose.models.Customer || mongoose.model<ICustomer>('Customer', CustomerSchema);
export const Supplier = mongoose.models.Supplier || mongoose.model<ISupplier>('Supplier', SupplierSchema);
export const PurchaseOrder = mongoose.models.PurchaseOrder || mongoose.model<IPurchaseOrder>('PurchaseOrder', PurchaseOrderSchema);
