import 'package:superport/models/address_model.dart';

/// 회사 유형 열거형
/// - 고객사: 서비스를 이용하는 회사
/// - 파트너사: 서비스를 제공하는 회사
enum CompanyType {
  customer, // 고객사
  partner, // 파트너사
}

/// 회사 유형을 문자열로 변환 (복수 지원)
String companyTypeToString(CompanyType type) {
  switch (type) {
    case CompanyType.customer:
      return '고객사';
    case CompanyType.partner:
      return '파트너사';
  }
}

/// 문자열에서 회사 유형으로 변환 (단일)
CompanyType stringToCompanyType(String type) {
  switch (type) {
    case '고객사':
      return CompanyType.customer;
    case '파트너사':
      return CompanyType.partner;
    default:
      return CompanyType.customer; // 기본값은 고객사
  }
}

/// 문자열 리스트에서 회사 유형 리스트로 변환
List<CompanyType> stringListToCompanyTypeList(List<dynamic> types) {
  // 중복 제거를 위한 Set 사용
  final Set<CompanyType> uniqueTypes = {};
  
  for (final e in types) {
    if (e is CompanyType) {
      uniqueTypes.add(e);
    } else if (e is String) {
      final normalized = e.toLowerCase().trim();
      if (normalized == 'partner' || normalized.contains('partner')) {
        uniqueTypes.add(CompanyType.partner);
      } else if (normalized == 'customer' || normalized.contains('customer')) {
        uniqueTypes.add(CompanyType.customer);
      } else if (normalized == 'other') {
        // "Other" 케이스는 고객사로 기본 매핑
        uniqueTypes.add(CompanyType.customer);
      }
    }
  }
  
  // 빈 경우 기본값 반환
  if (uniqueTypes.isEmpty) {
    return [CompanyType.customer];
  }
  
  return uniqueTypes.toList();
}

/// 회사 유형 리스트를 문자열 리스트로 변환
List<String> companyTypeListToStringList(List<CompanyType> types) {
  return types.map((e) => companyTypeToString(e)).toList();
}

class Branch {
  final int? id;
  final int companyId;
  final String name;
  final Address address; // 주소 모델 사용
  final String? contactName; // 담당자 이름
  final String? contactPosition; // 담당자 직책
  final String? contactPhone; // 담당자 전화번호
  final String? contactEmail; // 담당자 이메일
  final String? remark; // 비고

  Branch({
    this.id,
    required this.companyId,
    required this.name,
    Address? address, // 옵셔널 파라미터로 변경
    this.contactName,
    this.contactPosition,
    this.contactPhone,
    this.contactEmail,
    this.remark,
  }) : address = address ?? const Address(); // 기본값 제공

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'companyId': companyId,
      'name': name,
      'address': address.toString(), // 하위 호환성을 위해 문자열로 변환
      'addressData': address.toJson(), // 새로운 형식으로 저장
      'contactName': contactName,
      'contactPosition': contactPosition,
      'contactPhone': contactPhone,
      'contactEmail': contactEmail,
      'remark': remark,
    };
  }

  factory Branch.fromJson(Map<String, dynamic> json) {
    // 주소 데이터가 새 형식으로 저장되어 있는지 확인
    Address addressData;
    if (json.containsKey('addressData')) {
      addressData = Address.fromJson(json['addressData']);
    } else if (json.containsKey('address') && json['address'] != null) {
      // 이전 버전 호환성 - 문자열 주소를 Address 객체로 변환
      addressData = Address.fromFullAddress(json['address']);
    } else {
      addressData = const Address();
    }

    return Branch(
      id: json['id'],
      companyId: json['companyId'],
      name: json['name'],
      address: addressData,
      contactName: json['contactName'],
      contactPosition: json['contactPosition'],
      contactPhone: json['contactPhone'],
      contactEmail: json['contactEmail'],
      remark: json['remark'],
    );
  }

  /// 복사본을 생성하고 일부 필드를 업데이트합니다.
  Branch copyWith({
    int? id,
    int? companyId,
    String? name,
    Address? address,
    String? contactName,
    String? contactPosition,
    String? contactPhone,
    String? contactEmail,
    String? remark,
  }) {
    return Branch(
      id: id ?? this.id,
      companyId: companyId ?? this.companyId,
      name: name ?? this.name,
      address: address ?? this.address,
      contactName: contactName ?? this.contactName,
      contactPosition: contactPosition ?? this.contactPosition,
      contactPhone: contactPhone ?? this.contactPhone,
      contactEmail: contactEmail ?? this.contactEmail,
      remark: remark ?? this.remark,
    );
  }
}

class Company {
  final int? id;
  final String name;
  final Address address; // 주소 모델 사용
  final String? contactName; // 담당자 이름
  final String? contactPosition; // 담당자 직책
  final String? contactPhone; // 담당자 전화번호
  final String? contactEmail; // 담당자 이메일
  final List<Branch>? branches;
  final List<CompanyType> companyTypes; // 회사 유형 (복수 가능)
  final String? remark; // 비고
  final bool isActive; // 활성 상태
  final bool isPartner; // 파트너사 플래그
  final bool isCustomer; // 고객사 플래그
  final int? parentCompanyId; // 상위 회사 ID (계층형 구조)
  final DateTime? createdAt; // 생성일
  final DateTime? updatedAt; // 수정일

  Company({
    this.id,
    required this.name,
    Address? address, // 옵셔널 파라미터로 변경
    this.contactName,
    this.contactPosition,
    this.contactPhone,
    this.contactEmail,
    this.branches,
    this.companyTypes = const [CompanyType.customer], // 기본값은 고객사
    this.remark,
    this.isActive = true, // 기본값은 활성
    this.isPartner = false, // 기본값은 파트너 아님
    this.isCustomer = true, // 기본값은 고객사
    this.parentCompanyId, // 상위 회사 ID
    this.createdAt,
    this.updatedAt,
  }) : address = address ?? const Address(); // 기본값 제공

  Map<String, dynamic> toJson() {
    return {
      'id': id,
      'name': name,
      'address': address.toString(), // 하위 호환성을 위해 문자열로 변환
      'addressData': address.toJson(), // 새로운 형식으로 저장
      'contactName': contactName,
      'contactPosition': contactPosition,
      'contactPhone': contactPhone,
      'contactEmail': contactEmail,
      'branches': branches?.map((branch) => branch.toJson()).toList(),
      // 회사 유형을 문자열 리스트로 저장
      'companyTypes': companyTypes.map((e) => e.toString()).toList(),
      'remark': remark,
      'isActive': isActive,
      'isPartner': isPartner,
      'isCustomer': isCustomer,
      'parentCompanyId': parentCompanyId,
      'createdAt': createdAt?.toIso8601String(),
      'updatedAt': updatedAt?.toIso8601String(),
    };
  }

  factory Company.fromJson(Map<String, dynamic> json) {
    List<Branch>? branchList;
    if (json['branches'] != null) {
      branchList =
          (json['branches'] as List)
              .map((branchJson) => Branch.fromJson(branchJson))
              .toList();
    }

    // 주소 데이터가 새 형식으로 저장되어 있는지 확인
    Address addressData;
    if (json.containsKey('addressData')) {
      addressData = Address.fromJson(json['addressData']);
    } else if (json.containsKey('address') && json['address'] != null) {
      // 이전 버전 호환성 - 문자열 주소를 Address 객체로 변환
      addressData = Address.fromFullAddress(json['address']);
    } else {
      addressData = const Address();
    }

    // 회사 유형 파싱 (복수) - 서버 응답 우선
    List<CompanyType> types = [CompanyType.customer]; // 기본값
    if (json.containsKey('company_types')) {
      final raw = json['company_types'];
      if (raw is List) {
        types = stringListToCompanyTypeList(raw);
      }
    } else if (json.containsKey('companyTypes')) {
      final raw = json['companyTypes'];
      if (raw is List) {
        types = stringListToCompanyTypeList(raw);
      }
    } else if (json.containsKey('companyType')) {
      // 이전 버전 호환성: 단일 값
      final raw = json['companyType'];
      if (raw is String) {
        types = [stringToCompanyType(raw)];
      } else if (raw is int) {
        types = [CompanyType.values[raw]];
      }
    }

    return Company(
      id: json['id'],
      name: json['name'],
      address: addressData,
      contactName: json['contact_name'] ?? json['contactName'],
      contactPosition: json['contact_position'] ?? json['contactPosition'],
      contactPhone: json['contact_phone'] ?? json['contactPhone'],
      contactEmail: json['contact_email'] ?? json['contactEmail'],
      branches: branchList,
      companyTypes: types,
      remark: json['remark'],
      isActive: json['is_active'] ?? json['isActive'] ?? true,
      isPartner: json['is_partner'] ?? json['isPartner'] ?? false,
      isCustomer: json['is_customer'] ?? json['isCustomer'] ?? true,
      parentCompanyId: json['parent_company_id'] ?? json['parentCompanyId'],
      createdAt: json['created_at'] != null 
          ? DateTime.parse(json['created_at']) 
          : (json['createdAt'] != null ? DateTime.parse(json['createdAt']) : null),
      updatedAt: json['updated_at'] != null 
          ? DateTime.parse(json['updated_at']) 
          : (json['updatedAt'] != null ? DateTime.parse(json['updatedAt']) : null),
    );
  }

  /// 복사본을 생성하고 일부 필드를 업데이트합니다.
  Company copyWith({
    int? id,
    String? name,
    Address? address,
    String? contactName,
    String? contactPosition,
    String? contactPhone,
    String? contactEmail,
    List<Branch>? branches,
    List<CompanyType>? companyTypes,
    String? remark,
    bool? isActive,
    bool? isPartner,
    bool? isCustomer,
    int? parentCompanyId,
    DateTime? createdAt,
    DateTime? updatedAt,
  }) {
    return Company(
      id: id ?? this.id,
      name: name ?? this.name,
      address: address ?? this.address,
      contactName: contactName ?? this.contactName,
      contactPosition: contactPosition ?? this.contactPosition,
      contactPhone: contactPhone ?? this.contactPhone,
      contactEmail: contactEmail ?? this.contactEmail,
      branches: branches ?? this.branches,
      companyTypes: companyTypes ?? this.companyTypes,
      remark: remark ?? this.remark,
      isActive: isActive ?? this.isActive,
      isPartner: isPartner ?? this.isPartner,
      isCustomer: isCustomer ?? this.isCustomer,
      parentCompanyId: parentCompanyId ?? this.parentCompanyId,
      createdAt: createdAt ?? this.createdAt,
      updatedAt: updatedAt ?? this.updatedAt,
    );
  }
}
