generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "windows", "debian-openssl-1.0.x"]
}

datasource db {
  provider = "sqlite"
  url      = env("DATABASE_URL")
}

// المدرسة (v8): النظام متعدد المدارس — كل البيانات تنتمي لمدرسة عبر schoolId
model School {
  id        String   @id @default(cuid())
  name      String
  nameEn    String?
  address   String?
  phone     String?
  isActive  Boolean  @default(true)
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

// أدوار المستخدمين: SUPER_ADMIN (مدير النظام العام) | ADMIN (مدير مدرسة) | ACCOUNTANT (محاسب) | STAFF (إداري)
model User {
  id           String   @id @default(cuid())
  username     String   @unique
  passwordHash String
  fullName     String
  phone        String?  // رقم التواصل المعتمد لاسترداد الحساب
  recoveryCodeHash String? // بصمة رمز الاسترداد؛ لا يُحفظ الرمز الصريح
  passwordChangedAt DateTime?
  role         String   @default("STAFF")
  // المدرسة التي ينتمي إليها المستخدم — null لمدير النظام العام (SUPER_ADMIN) فقط
  schoolId     String?
  isActive     Boolean  @default(true)
  // تاريخ حذف الحساب (حذف منطقي) — null = غير محذوف، المحذوف لا يستطيع الدخول ويظهر في قسم الحسابات المحذوفة
  deletedAt    DateTime?
  // الصفحات المسموح للمستخدم بالوصول إليها (JSON array) - null أو فارغة = الصلاحيات الافتراضية للدور
  allowedViews String?
  createdAt    DateTime @default(now())
  updatedAt    DateTime @updatedAt
  payments     Payment[]
  expenses     Expense[]
  announcements Announcement[]
  employeePayments EmployeePayment[]
  supplierPayments SupplierPayment[]
  otherIncomes OtherIncome[]

  @@index([phone])
}

// الشعب الدراسية الديناميكية (أ، ب، ج ...) — لكل مدرسة شعبها الخاصة
model Classroom {
  id        String   @id @default(cuid())
  name      String
  schoolId  String?
  createdAt DateTime @default(now())

  @@unique([schoolId, name])
}

// صفوف إضافية يضيفها المدير (غير الثابتة في النظام) — لكل مدرسة صفوفها
model CustomGrade {
  id        String   @id @default(cuid())
  code      String // يُستخدم في توليد كود الطالب مثل CG1-2026-0001
  nameAr    String
  schoolId  String?
  createdAt DateTime @default(now())

  @@unique([schoolId, code])
  @@unique([schoolId, nameAr])
}

// صفوف أساسية أخفاها المدير — لكل مدرسة إخفاؤها الخاص
model HiddenGrade {
  code      String // كود الصف الأساسي مثل G3
  schoolId  String
  createdAt DateTime @default(now())

  @@id([code, schoolId])
}

model Student {
  id              String    @id @default(cuid())
  studentCode     String
  nameAr          String
  nameEn          String
  grade           String
  classroom       String
  guardianName    String
  guardianPhone   String
  guardianAddress String?
  notes           String?
  totalFee        Float     @default(0)
  discountPercent Float     @default(0)
  feeDueDate      DateTime?
  // تاريخ التسجيل الفعلي الذي يحدده الموظف (قد يكون بتاريخ سابق مثل شهر آب) — أساس حساب تقسيط الـ 8 أشهر
  registeredAt    DateTime  @default(now())
  isActive        Boolean   @default(true)
  createdAt       DateTime  @default(now())
  updatedAt       DateTime  @updatedAt
  payments        Payment[]
  installments    Installment[]
  registeredById  String?
  // المدرسة التي ينتمي إليها الطالب
  schoolId        String?

  @@unique([schoolId, studentCode])
  @@index([schoolId])
}

model Payment {
  id              String   @id @default(cuid())
  receiptNumber   String
  studentId       String
  student         Student  @relation(fields: [studentId], references: [id])
  amount          Float
  installmentType String   @default("قسط أول")
  method          String   @default("CASH")
  transactionRef  String?
  notes           String?
  paidAt          DateTime @default(now())
  createdAt       DateTime @default(now())
  createdById     String
  creator         User?    @relation(fields: [createdById], references: [id])
  schoolId        String?

  @@unique([schoolId, receiptNumber])
  @@index([schoolId])
}

model Expense {
  id          String   @id @default(cuid())
  category    String
  description String
  amount      Float
  // رقم وصل الصرف (v8.1) — لضمان التدقيق المالي ومطابقة السندات الورقية
  voucherNumber String?
  // التصنيف المالي الموحد (v8.1): SALARY | LECTURE_WAGE | STAFF_LOAN_GIVEN | ACTIVITY_LOAN_GIVEN
  //   | MAINTENANCE | OPERATIONAL | COMPANY_INVOICE | LOAN | TRANSFER | OTHER
  kind        String   @default("OTHER")
  invoiceName String?
  invoiceData String?
  spentAt     DateTime
  createdAt   DateTime @default(now())
  createdById String
  creator     User?    @relation(fields: [createdById], references: [id])
  employeePayments EmployeePayment[]
  supplierPayments SupplierPayment[]
  lectureWages LectureWage[]
  staffLoans  EmployeeLoan[]
  activityLoans ActivityLoan[]
  schoolId    String?

  @@index([schoolId, kind])
  @@index([schoolId, spentAt])
}

// موظفو المدرسة (معلمون وإداريون) — حذف منطقي عبر deletedAt
model Employee {
  id            String    @id @default(cuid())
  name          String
  role          String
  monthlySalary Float
  startDate     DateTime
  // نوع الكادر (v8.1): TEACHER (تدريسي) | ADMIN (إداري) — يحدد أهلية احتساب أجور المحاضرات
  employeeType  String    @default("ADMIN")
  // سعر المحاضرة الواحدة للمعلمين (v8.1) — أجر المحاضرة = السعر × عدد المحاضرات الشهرية
  lecturePrice  Float     @default(0)
  // إيقاف مؤقت = false (للعرض في الحالة فقط — الاستحقاق يُحسب من تاريخ المباشر)
  isActive      Boolean   @default(true)
  deletedAt     DateTime?
  createdAt     DateTime  @default(now())
  updatedAt     DateTime  @updatedAt
  payments      EmployeePayment[]
  lectureWages  LectureWage[]
  loans         EmployeeLoan[]
  schoolId      String?

  @@index([schoolId, employeeType])
}

// دفعة راتب لموظف — تُسجل مصروفاً تلقائياً بفئة رواتب الموظفين
// v8.1: كشف رواتب تفصيلي — المبلغ الاسمي، الخصومات والاستقطاعات، المكافآت والزيادات، رقم وصل الصرف
model EmployeePayment {
  id         String    @id @default(cuid())
  employeeId String
  employee   Employee  @relation(fields: [employeeId], references: [id])
  amount     Float
  // المبلغ الاسمي (الراتب الأساسي قبل الخصومات والمكافآت) — v8.1
  baseAmount Float     @default(0)
  // الخصومات والاستقطاعات — v8.1
  deductions Float     @default(0)
  // المكافآت والزيادات — v8.1
  bonuses    Float     @default(0)
  // رقم وصل الصرف — v8.1 (يُولد تلقائياً إذا غاب)
  voucherNumber String?
  paidAt     DateTime  @default(now())
  notes      String?
  // المصروف المرتبط (يُحذف/يُعدل تلقائياً مع الدفعة ليبقى الرصيد صحيحاً)
  expenseId  String?   @unique
  expense    Expense?  @relation(fields: [expenseId], references: [id])
  creatorId  String?
  creator    User?     @relation(fields: [creatorId], references: [id])
  createdAt  DateTime  @default(now())
}

// شركة / مورد تعامل معها المدرسة — حذف منطقي
model Supplier {
  id        String    @id @default(cuid())
  name      String
  phone     String?
  notes     String?
  deletedAt DateTime?
  createdAt DateTime  @default(now())
  updatedAt DateTime  @updatedAt
  invoices  SupplierInvoice[]
  payments  SupplierPayment[]
  schoolId  String?
}

// فاتورة آجلة من شركة (الدين = مجموع الفواتير - مجموع الدفعات)
model SupplierInvoice {
  id          String   @id @default(cuid())
  supplierId  String
  supplier    Supplier @relation(fields: [supplierId], references: [id])
  description String
  amount      Float
  invoiceDate DateTime @default(now())
  createdAt   DateTime @default(now())
  payments    SupplierPayment[]
}

// دفعة مسددة لشركة — تُسجل مصروفاً تلقائياً بفئة فواتير الشركات
model SupplierPayment {
  id         String           @id @default(cuid())
  supplierId String
  supplier   Supplier         @relation(fields: [supplierId], references: [id])
  invoiceId  String?
  invoice    SupplierInvoice? @relation(fields: [invoiceId], references: [id])
  amount     Float
  paidAt     DateTime         @default(now())
  notes      String?
  expenseId  String?          @unique
  expense    Expense?         @relation(fields: [expenseId], references: [id])
  creatorId  String?
  creator    User?            @relation(fields: [creatorId], references: [id])
  createdAt  DateTime         @default(now())
}

model Announcement {
  id          String   @id @default(cuid())
  message     String
  level       String   @default("INFO")
  isActive    Boolean  @default(true)
  createdAt   DateTime @default(now())
  createdById String
  creator     User?    @relation(fields: [createdById], references: [id])
  schoolId    String?
}

model OtherIncome {
  id          String   @id @default(cuid())
  source      String   // جهة الإيراد (من أين جاء المال)
  reason      String   // سبب الإيراد (عن ماذا)
  amount      Float
  // بند الإيراد (v8.1): OTHER_SCHOOL (واردات مدارس أخرى) | STAFF_LOAN_REPAY (تسديد سلف منتسبين)
  //   | ACTIVITY_LOAN_REPAY (تسديد سلف نشاطات) | TRANSFER (مناقلة) | OTHER (إيرادات خارجية أخرى)
  kind        String   @default("OTHER")
  notes       String?
  receivedAt  DateTime @default(now()) // تاريخ استلام الإيراد
  createdAt   DateTime @default(now())
  createdById String
  creator     User?    @relation(fields: [createdById], references: [id])
  staffLoanRepayments EmployeeLoanRepayment[]
  activityLoanRepayments ActivityLoanRepayment[]
  schoolId    String?

  @@index([schoolId, kind])
}

// جدول أقساط الطالب (v8.1) — الترحيل الآلي: كل دفعة تُخصص تلقائياً للأقساط غير المسددة
model Installment {
  id         String   @id @default(cuid())
  studentId  String
  student    Student  @relation(fields: [studentId], references: [id], onDelete: Cascade)
  seq        Int      // رقم القسط (1..8)
  dueDate    DateTime // تاريخ الاستحقاق (شهر من تاريخ التسجيل)
  amount     Float    // مبلغ القسط (الصافي بعد الخصم ÷ 8)
  paidAmount Float    @default(0) // المسدد من هذا القسط
  status     String   @default("UNPAID") // UNPAID | PARTIAL | PAID
  createdAt  DateTime @default(now())
  updatedAt  DateTime @updatedAt

  @@unique([studentId, seq])
  @@index([studentId])
}

// سلفة منتسبين (v8.1) — مبلغ مقرض لموظف، يُسجل مصروفاً تلقائياً (STAFF_LOAN_GIVEN) ويسدد لاحقاً
model EmployeeLoan {
  id          String    @id @default(cuid())
  employeeId  String
  employee    Employee  @relation(fields: [employeeId], references: [id], onDelete: Cascade)
  amount      Float
  reason      String
  loanedAt    DateTime  @default(now())
  notes       String?
  expenseId   String?   @unique
  expense     Expense?  @relation(fields: [expenseId], references: [id])
  repayments  EmployeeLoanRepayment[]
  creatorId   String?
  createdAt   DateTime  @default(now())
  schoolId    String?
}

// تسديد سلفة منتسبين — يُسجل إيراداً تلقائياً (STAFF_LOAN_REPAY)
model EmployeeLoanRepayment {
  id            String      @id @default(cuid())
  loanId        String
  loan          EmployeeLoan @relation(fields: [loanId], references: [id], onDelete: Cascade)
  amount        Float
  paidAt        DateTime    @default(now())
  notes         String?
  otherIncomeId String?     @unique
  otherIncome   OtherIncome? @relation(fields: [otherIncomeId], references: [id])
  creatorId     String?
  createdAt     DateTime    @default(now())
  schoolId      String?
}

// سلفة نشاط (v8.1) — مبلغ مقرض لنشاط/جهة، يُسجل مصروفاً تلقائياً (ACTIVITY_LOAN_GIVEN) ويسدد لاحقاً
model ActivityLoan {
  id          String    @id @default(cuid())
  name        String    // اسم النشاط أو الجهة
  amount      Float
  reason      String
  loanedAt    DateTime  @default(now())
  notes       String?
  expenseId   String?   @unique
  expense     Expense?  @relation(fields: [expenseId], references: [id])
  repayments  ActivityLoanRepayment[]
  creatorId   String?
  createdAt   DateTime  @default(now())
  schoolId    String?
}

// تسديد سلفة نشاط — يُسجل إيراداً تلقائياً (ACTIVITY_LOAN_REPAY)
model ActivityLoanRepayment {
  id            String       @id @default(cuid())
  loanId        String
  loan          ActivityLoan @relation(fields: [loanId], references: [id], onDelete: Cascade)
  amount        Float
  paidAt        DateTime     @default(now())
  notes         String?
  otherIncomeId String?      @unique
  otherIncome   OtherIncome? @relation(fields: [otherIncomeId], references: [id])
  creatorId     String?
  createdAt     DateTime     @default(now())
  schoolId      String?
}

// أجور المحاضرات (v8.1) — لكل معلم شهرياً: سعر المحاضرة × عدد المحاضرات
// تُسجل مصروفاً تلقائياً (LECTURE_WAGE) عند الدفع
model LectureWage {
  id           String    @id @default(cuid())
  employeeId   String
  employee     Employee  @relation(fields: [employeeId], references: [id], onDelete: Cascade)
  month        String    // شهر الاستحقاق بصيغة YYYY-MM
  lectureCount Int       // عدد المحاضرات في الشهر
  lecturePrice Float     // سعر المحاضرة الواحدة (يُلتقط من الموظف وقت التسجيل)
  total        Float     // أجر الشهر = العدد × السعر
  notes        String?
  paidAt       DateTime? // تاريخ الصرف — null = غير مصروفة
  voucherNumber String?  // رقم وصل الصرف عند الدفع
  expenseId    String?   @unique
  expense      Expense?  @relation(fields: [expenseId], references: [id])
  creatorId    String?
  createdAt    DateTime  @default(now())
  schoolId     String?

  @@unique([employeeId, month])
  @@index([schoolId, month])
}

model AuditLog {
  id        String   @id @default(cuid())
  userId    String?
  userName  String?
  role      String?
  action    String
  entity    String
  entityId  String?
  details   String?
  createdAt DateTime @default(now())
}

model SchoolSettings {
  id         String   @id @default("main")
  nameAr     String   @default("مدرسة الأمل الأهلية")
  nameEn     String   @default("Al-Amal Private School")
  logoData   String?
  address    String?
  phone      String?
  email      String?
  currency   String   @default("د.ع")
  footerText String?
  // الرصيد الافتتاحي للصندوق (v8.1) — أساس حساب الرصيد المدور في تقرير الميزانية الشهرية
  openingBalance Float @default(0)
  updatedAt  DateTime @updatedAt
}
