enum TenantKind { lab, clinic }

enum TenantRole {
  owner,
  admin,
  technician, // lab: işler + ürünler
  delivery,   // lab: işler
  finance,    // lab+clinic: finans
  doctor,     // clinic: işler + hastalar
  member,     // legacy — full access
  ;

  String get value => name;

  String get label => switch (this) {
        TenantRole.owner      => 'Sahibi',
        TenantRole.admin      => 'Yönetici',
        TenantRole.technician => 'Teknisyen',
        TenantRole.delivery   => 'Teslimat Elemanı',
        TenantRole.finance    => 'Finans Elemanı',
        TenantRole.doctor     => 'Hekim',
        TenantRole.member     => 'Üye',
      };
}

enum TenantPlan { starter, pro, enterprise }

class Tenant {
  const Tenant({
    required this.id,
    required this.kind,
    required this.memberNumber,
    required this.companyName,
    this.logo,
    this.defaultCurrency = 'TRY',
    this.status = 'active',
    this.plan,
    this.maxMembers,
  });

  final String id;
  final TenantKind kind;
  final String memberNumber;
  final String companyName;
  final String? logo;
  final String defaultCurrency;
  final String status;
  final TenantPlan? plan;
  final int? maxMembers;

  bool get isLab => kind == TenantKind.lab;
  bool get isClinic => kind == TenantKind.clinic;

  factory Tenant.fromJson(Map<String, dynamic> j) => Tenant(
        id: j['id'] as String,
        kind: j['kind'] == 'lab' ? TenantKind.lab : TenantKind.clinic,
        memberNumber: (j['member_number'] as String?) ?? '',
        companyName: j['company_name'] as String,
        logo: j['logo'] as String?,
        defaultCurrency: (j['default_currency'] as String?) ?? 'TRY',
        status: (j['status'] as String?) ?? 'active',
        plan: _parsePlan(j['plan'] as String?),
        maxMembers: (j['max_members'] as num?)?.toInt(),
      );

  static TenantPlan? _parsePlan(String? p) => switch (p) {
        'starter' => TenantPlan.starter,
        'pro' => TenantPlan.pro,
        'enterprise' => TenantPlan.enterprise,
        _ => null,
      };
}

class TenantMembership {
  const TenantMembership({
    required this.id,
    required this.tenant,
    required this.role,
  });

  final String id;
  final Tenant tenant;
  final TenantRole role;

  // ── Access helpers ────────────────────────────────────────────────────────
  bool get isOwner => role == TenantRole.owner;
  bool get isAdmin => role == TenantRole.admin || role == TenantRole.owner;
  bool get canManageUsers => role == TenantRole.owner || role == TenantRole.admin;
  bool get canManageJobs => role != TenantRole.finance;
  bool get canManageFinance => role == TenantRole.owner || role == TenantRole.admin || role == TenantRole.finance || role == TenantRole.member;
  bool get canManageProducts => role == TenantRole.owner || role == TenantRole.admin || role == TenantRole.technician || role == TenantRole.member;
  bool get canViewPatients => role == TenantRole.owner || role == TenantRole.admin || role == TenantRole.doctor || role == TenantRole.member;
  bool get canManageConnections => role == TenantRole.owner || role == TenantRole.admin || role == TenantRole.member;

  // ── Fine-grained job actions ──────────────────────────────────────────────
  /// Can create new jobs (clinic side: owner/admin/doctor/member; not delivery/finance)
  bool get canCreateJobs => role != TenantRole.delivery && role != TenantRole.finance;

  /// Can confirm physical delivery (delivery role + supervisors)
  bool get canDeliverJobs => role != TenantRole.finance;

  /// Can cancel or fully manage job lifecycle (not delivery-only or finance)
  bool get canCancelJobs => role == TenantRole.owner || role == TenantRole.admin || role == TenantRole.member || role == TenantRole.doctor;

  /// Primary focus is delivery — restrict to delivery-relevant UI
  bool get isDeliveryOnly => role == TenantRole.delivery;

  // ── Nav visibility ────────────────────────────────────────────────────────
  bool get showDashboard => true;
  bool get showJobs => canManageJobs;
  bool get showProducts => tenant.isLab && canManageProducts;
  bool get showPatients => tenant.isClinic && canViewPatients;
  bool get showConnections => canManageConnections;
  bool get showFinance => canManageFinance;

  factory TenantMembership.fromJson(Map<String, dynamic> j) {
    final expand = j['expand'] as Map<String, dynamic>?;
    final tenantData = expand?['tenant_id'] as Map<String, dynamic>?;
    return TenantMembership(
      id: j['id'] as String,
      tenant: Tenant.fromJson(tenantData!),
      role: parseRole(j['role'] as String),
    );
  }

  static TenantRole parseRole(String r) => switch (r) {
        'owner'      => TenantRole.owner,
        'admin'      => TenantRole.admin,
        'technician' => TenantRole.technician,
        'delivery'   => TenantRole.delivery,
        'finance'    => TenantRole.finance,
        'doctor'     => TenantRole.doctor,
        _            => TenantRole.member,
      };

  String get roleLabel => switch (role) {
        TenantRole.owner      => 'Sahibi',
        TenantRole.admin      => 'Yönetici',
        TenantRole.technician => 'Teknisyen',
        TenantRole.delivery   => 'Teslimat Elemanı',
        TenantRole.finance    => 'Finans Elemanı',
        TenantRole.doctor     => 'Hekim',
        TenantRole.member     => 'Üye',
      };
}
