import 'package:superport/models/equipment_unified_model.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/user_model.dart';
import 'package:superport/models/license_model.dart';
import 'package:superport/models/address_model.dart';
import 'package:superport/models/warehouse_location_model.dart';
import 'package:superport/utils/constants.dart'; // 장비 상태/유형 상수 import

class MockDataService {
  // 싱글톤 패턴
  static final MockDataService _instance = MockDataService._internal();

  // 정적 초기화 플래그
  static bool _isInitialized = false;

  factory MockDataService() => _instance;

  MockDataService._internal() {
    // 정적 플래그를 사용하여 딱 한 번만 초기화
    if (!_isInitialized) {
      initialize();
      _isInitialized = true;
    }
  }

  // 모의 데이터 저장소
  final List<EquipmentIn> _equipmentIns = [];
  final List<EquipmentOut> _equipmentOuts = [];
  final List<Company> _companies = [];
  final List<User> _users = [];
  final List<License> _licenses = [];
  final List<WarehouseLocation> _warehouseLocations = [];

  // ID 카운터
  int _equipmentInIdCounter = 1;
  int _equipmentOutIdCounter = 1;
  int _companyIdCounter = 1;
  int _userIdCounter = 1;
  int _licenseIdCounter = 1;
  int _warehouseLocationIdCounter = 1;

  // 초기 데이터 생성
  void initialize() {
    // 본사 지점명 및 주소 변경을 위한 함수
    Branch _convertHeadOfficeBranch(Branch branch, int companyId) {
      // 이름이 '본사'인 경우만 변환
      if (branch.name == '본사') {
        // 본사 지점의 이름을 '중앙지점'으로, 주소를 임의의 다른 값으로 변경
        return Branch(
          id: branch.id,
          companyId: companyId,
          name: '중앙지점', // 본사 → 중앙지점으로 변경
          address: Address(
            zipCode: '04533', // 임의의 다른 우편번호
            region: '서울특별시', // 임의의 다른 지역
            detailAddress: '중구 을지로 100', // 임의의 다른 상세주소
          ),
          contactName: branch.contactName,
          contactPosition: branch.contactPosition,
          contactPhone: branch.contactPhone,
          contactEmail: branch.contactEmail,
        );
      }
      // 본사가 아니면 그대로 반환
      return branch;
    }

    // 모의 회사 데이터 추가
    addCompany(
      Company(
        name: 'LG전자',
        address: Address(
          zipCode: '03184',
          region: '서울특별시',
          detailAddress: '종로구 새문안로 58',
        ),
        contactName: '김영수',
        contactPosition: '팀장',
        contactPhone: '010-1234-5678',
        contactEmail: 'kim.youngsoo@lg.com',
        companyTypes: [CompanyType.customer, CompanyType.partner], // 고객사+파트너사
        branches: [
          _convertHeadOfficeBranch(
            Branch(
              companyId: 1,
              name: '본사',
              address: Address(
                zipCode: '03184',
                region: '서울특별시',
                detailAddress: '종로구 새문안로 58',
              ),
              contactName: '박지은',
              contactPosition: '과장',
              contactPhone: '010-2345-6789',
              contactEmail: 'park.jieun@lg.com',
            ),
            1,
          ),
          Branch(
            companyId: 1,
            name: '강남지점',
            address: Address(
              zipCode: '06194',
              region: '서울특별시',
              detailAddress: '강남구 테헤란로 534',
            ),
            contactName: '이민호',
            contactPosition: '대리',
            contactPhone: '010-3456-7890',
            contactEmail: 'lee.minho@lg.com',
          ),
          Branch(
            companyId: 1,
            name: '판교지점',
            address: Address(
              zipCode: '13494',
              region: '경기도',
              detailAddress: '성남시 분당구 판교로 160',
            ),
            contactName: '정수진',
            contactPosition: '사원',
            contactPhone: '010-4567-8901',
            contactEmail: 'jung.soojin@lg.com',
          ),
        ],
      ),
    );

    addCompany(
      Company(
        name: '삼성전자',
        address: Address(
          zipCode: '06620',
          region: '서울특별시',
          detailAddress: '서초구 서초대로 74길 11',
        ),
        contactName: '최동욱',
        contactPosition: '부장',
        contactPhone: '010-5678-9012',
        contactEmail: 'choi.dongwook@samsung.com',
        companyTypes: [CompanyType.partner], // 파트너사
        branches: [
          _convertHeadOfficeBranch(
            Branch(
              companyId: 2,
              name: '본사',
              address: Address(
                zipCode: '06620',
                region: '서울특별시',
                detailAddress: '서초구 서초대로 74길 11',
              ),
              contactName: '한미영',
              contactPosition: '팀장',
              contactPhone: '010-6789-0123',
              contactEmail: 'han.miyoung@samsung.com',
            ),
            2,
          ),
          Branch(
            companyId: 2,
            name: '수원사업장',
            address: Address(
              zipCode: '16677',
              region: '경기도',
              detailAddress: '수원시 영통구 삼성로 129',
            ),
            contactName: '장현우',
            contactPosition: '과장',
            contactPhone: '010-7890-1234',
            contactEmail: 'jang.hyunwoo@samsung.com',
          ),
        ],
      ),
    );

    addCompany(
      Company(
        name: '현대자동차',
        address: Address(
          zipCode: '06797',
          region: '서울특별시',
          detailAddress: '서초구 헌릉로 12',
        ),
        contactName: '김태희',
        contactPosition: '상무',
        contactPhone: '010-8901-2345',
        contactEmail: 'kim.taehee@hyundai.com',
        companyTypes: [CompanyType.customer], // 고객사
        branches: [
          _convertHeadOfficeBranch(
            Branch(
              companyId: 3,
              name: '본사',
              address: Address(
                zipCode: '06797',
                region: '서울특별시',
                detailAddress: '서초구 헌릉로 12',
              ),
              contactName: '이준호',
              contactPosition: '팀장',
              contactPhone: '010-9012-3456',
              contactEmail: 'lee.junho@hyundai.com',
            ),
            3,
          ),
          Branch(
            companyId: 3,
            name: '울산공장',
            address: Address(
              zipCode: '44100',
              region: '울산광역시',
              detailAddress: '북구 산업로 1000',
            ),
            contactName: '송지원',
            contactPosition: '대리',
            contactPhone: '010-0123-4567',
            contactEmail: 'song.jiwon@hyundai.com',
          ),
        ],
      ),
    );

    addCompany(
      Company(
        name: 'SK하이닉스',
        address: Address(
          zipCode: '17084',
          region: '경기도',
          detailAddress: '이천시 부발읍 경충대로 2091',
        ),
        contactName: '박서준',
        contactPosition: '이사',
        contactPhone: '010-1122-3344',
        contactEmail: 'park.seojoon@sk.com',
        companyTypes: [CompanyType.partner, CompanyType.customer], // 파트너사+고객사
        branches: [
          _convertHeadOfficeBranch(
            Branch(
              companyId: 4,
              name: '본사',
              address: Address(
                zipCode: '17084',
                region: '경기도',
                detailAddress: '이천시 부발읍 경충대로 2091',
              ),
              contactName: '강지영',
              contactPosition: '팀장',
              contactPhone: '010-2233-4455',
              contactEmail: 'kang.jiyoung@sk.com',
            ),
            4,
          ),
          Branch(
            companyId: 4,
            name: '청주사업장',
            address: Address(
              zipCode: '28422',
              region: '충청북도',
              detailAddress: '청주시 흥덕구 대신로 215',
            ),
            contactName: '윤성민',
            contactPosition: '과장',
            contactPhone: '010-3344-5566',
            contactEmail: 'yoon.sungmin@sk.com',
          ),
        ],
      ),
    );

    // 모의 사용자 데이터 추가
    addUser(
      User(
        companyId: 1,
        name: '홍길동',
        role: 'S', // 관리자
        email: 'admin@superport.com',
      ),
    );

    addUser(
      User(
        companyId: 1,
        name: '김철수',
        role: 'M', // 멤버
        email: 'kim.cs@samsung.com',
      ),
    );

    // ===== 실제 네트워크/IT 장비 및 소모품 기반 입고 샘플 데이터 20개 추가 =====
    final List<Map<String, dynamic>> realEquipments = [
      // 시리얼넘버가 있는 네트워크/IT 장비 (수량 1)
      {
        'manufacturer': 'Cisco',
        'name': 'Catalyst 9300',
        'category': '네트워크',
        'subCategory': '스위치',
        'subSubCategory': 'Layer3',
        'serialNumber': 'FDO1234A1BC',
        'barcode': 'CISCO9300-001',
      },
      {
        'manufacturer': 'HPE',
        'name': 'Aruba 2930F',
        'category': '네트워크',
        'subCategory': '스위치',
        'subSubCategory': 'Layer2',
        'serialNumber': 'CN12345678',
        'barcode': 'ARUBA2930F-001',
      },
      {
        'manufacturer': 'Dell',
        'name': 'PowerEdge R740',
        'category': '서버',
        'subCategory': '랙마운트',
        'subSubCategory': '2U',
        'serialNumber': '6JH1234',
        'barcode': 'DELLR740-001',
      },
      {
        'manufacturer': 'Juniper',
        'name': 'EX4300',
        'category': '네트워크',
        'subCategory': '스위치',
        'subSubCategory': 'Layer3',
        'serialNumber': 'JNPR123456',
        'barcode': 'JUNEX4300-001',
      },
      {
        'manufacturer': 'Fortinet',
        'name': 'FortiGate 100F',
        'category': '보안',
        'subCategory': '방화벽',
        'subSubCategory': 'UTM',
        'serialNumber': 'FGT100F1234',
        'barcode': 'FORTI100F-001',
      },
      {
        'manufacturer': 'Mikrotik',
        'name': 'CCR1009',
        'category': '네트워크',
        'subCategory': '라우터',
        'subSubCategory': 'Cloud Core',
        'serialNumber': 'MKTKCCR1009',
        'barcode': 'MIKROCCR1009-001',
      },
      {
        'manufacturer': 'Ubiquiti',
        'name': 'UniFi AP AC Pro',
        'category': '네트워크',
        'subCategory': '무선AP',
        'subSubCategory': 'WiFi5',
        'serialNumber': 'UBNTUAPACPRO',
        'barcode': 'UBNTUAPACPRO-001',
      },
      {
        'manufacturer': 'Netgear',
        'name': 'GS108',
        'category': '네트워크',
        'subCategory': '스위치',
        'subSubCategory': 'SOHO',
        'serialNumber': 'NGGS108SN01',
        'barcode': 'NETGEARGS108-001',
      },
      {
        'manufacturer': 'Aruba',
        'name': 'Instant On 1930',
        'category': '네트워크',
        'subCategory': '스위치',
        'subSubCategory': 'SMB',
        'serialNumber': 'ARUBA1930SN',
        'barcode': 'ARUBA1930-001',
      },
      {
        'manufacturer': 'TP-Link',
        'name': 'TL-SG3428',
        'category': '네트워크',
        'subCategory': '스위치',
        'subSubCategory': 'L2+',
        'serialNumber': 'TPLSG3428SN',
        'barcode': 'TPLINKSG3428-001',
      },
      {
        'manufacturer': '삼성',
        'name': 'Galaxy Book Pro',
        'category': '노트북',
        'subCategory': '울트라북',
        'subSubCategory': 'i7',
        'serialNumber': 'SMSGALBOOKPRO',
        'barcode': 'SMSGALBOOKPRO-001',
      },
      {
        'manufacturer': 'LG',
        'name': 'Gram 16',
        'category': '노트북',
        'subCategory': '경량',
        'subSubCategory': 'i5',
        'serialNumber': 'LGGRAM16SN',
        'barcode': 'LGGRAM16-001',
      },
      {
        'manufacturer': 'Apple',
        'name': 'MacBook Pro 14',
        'category': '노트북',
        'subCategory': 'Mac',
        'subSubCategory': 'M1 Pro',
        'serialNumber': 'MBP14M1PRO',
        'barcode': 'APPLEMBP14-001',
      },
      {
        'manufacturer': 'Lenovo',
        'name': 'ThinkPad X1 Carbon',
        'category': '노트북',
        'subCategory': '비즈니스',
        'subSubCategory': 'Gen9',
        'serialNumber': 'LNVX1CARBON',
        'barcode': 'LENOVOX1-001',
      },
      {
        'manufacturer': 'HP',
        'name': 'EliteBook 840',
        'category': '노트북',
        'subCategory': '비즈니스',
        'subSubCategory': 'G8',
        'serialNumber': 'HPEB840G8',
        'barcode': 'HPEB840-001',
      },
      // 시리얼넘버 없는 소모품 (수량만 존재)
      {
        'manufacturer': 'Logitech',
        'name': 'M720 Triathlon',
        'category': '입력장치',
        'subCategory': '마우스',
        'subSubCategory': '무선',
        'quantity': 15,
      },
      {
        'manufacturer': 'Samsung',
        'name': 'AA-SK2PWBB',
        'category': '입력장치',
        'subCategory': '키보드',
        'subSubCategory': '유선',
        'quantity': 10,
      },
      {
        'manufacturer': 'Anker',
        'name': 'PowerCore 10000',
        'category': '액세서리',
        'subCategory': '보조배터리',
        'subSubCategory': '10000mAh',
        'quantity': 8,
      },
      {
        'manufacturer': 'Xiaomi',
        'name': 'Mi Power Bank 3',
        'category': '액세서리',
        'subCategory': '보조배터리',
        'subSubCategory': '20000mAh',
        'quantity': 12,
      },
      {
        'manufacturer': 'LG',
        'name': 'MK430',
        'category': '입력장치',
        'subCategory': '키보드',
        'subSubCategory': '무선',
        'quantity': 7,
      },
    ];

    // 입고 데이터 생성
    for (int i = 0; i < 20; i++) {
      final eq = realEquipments[i % realEquipments.length];
      addEquipmentIn(
        EquipmentIn(
          equipment: Equipment(
            manufacturer: eq['manufacturer'],
            name: eq['name'],
            category: eq['category'],
            subCategory: eq['subCategory'],
            subSubCategory: eq['subSubCategory'],
            serialNumber: eq['serialNumber'],
            barcode: eq['barcode'],
            quantity: eq['serialNumber'] != null ? 1 : eq['quantity'],
          ),
          inDate: DateTime.now().subtract(Duration(days: 2 * i)),
          warehouseLocation: '입고지${i % 3 + 1}',
          partnerCompany: '파트너사${i % 4 + 1}',
          type: i % 2 == 0 ? EquipmentType.new_ : EquipmentType.used,
          remark:
              eq['serialNumber'] != null
                  ? '실제 네트워크/IT 장비 입고 샘플'
                  : '실제 소모품 입고 샘플',
        ),
      );
    }

    // 출고 데이터 생성
    for (int i = 0; i < 20; i++) {
      final eq = realEquipments[(i + 3) % realEquipments.length];
      addEquipmentOut(
        EquipmentOut(
          equipment: Equipment(
            manufacturer: eq['manufacturer'],
            name: eq['name'],
            category: eq['category'],
            subCategory: eq['subCategory'],
            subSubCategory: eq['subSubCategory'],
            serialNumber: eq['serialNumber'],
            barcode: eq['barcode'],
            quantity: eq['serialNumber'] != null ? 1 : eq['quantity'],
          ),
          outDate: DateTime.now().subtract(Duration(days: 3 * i)),
          status: EquipmentStatus.out,
          company: '출고회사${i % 4 + 1}',
          manager: '담당자${i % 6 + 1}',
          license: '라이센스${i % 2 + 1}',
          returnDate: null,
          returnType: null,
          remark:
              eq['serialNumber'] != null
                  ? '실제 네트워크/IT 장비 출고 샘플'
                  : '실제 소모품 출고 샘플',
        ),
      );
    }

    // 대여 데이터 생성
    for (int i = 0; i < 20; i++) {
      final eq = realEquipments[(i + 5) % realEquipments.length];
      addEquipmentOut(
        EquipmentOut(
          equipment: Equipment(
            manufacturer: eq['manufacturer'],
            name: eq['name'],
            category: eq['category'],
            subCategory: eq['subCategory'],
            subSubCategory: eq['subSubCategory'],
            serialNumber: eq['serialNumber'],
            barcode: eq['barcode'],
            quantity: eq['serialNumber'] != null ? 1 : eq['quantity'],
          ),
          outDate: DateTime.now().subtract(Duration(days: 4 * i)),
          status: EquipmentStatus.rent, // 대여 상태 코드 'T'
          company: '대여회사${i % 5 + 1}',
          manager: '대여담당자${i % 7 + 1}',
          license: '대여라이센스${i % 3 + 1}',
          returnDate:
              eq['serialNumber'] != null
                  ? DateTime.now().subtract(Duration(days: 4 * i - 2))
                  : null,
          returnType: eq['serialNumber'] != null ? '정상반납' : null,
          remark:
              eq['serialNumber'] != null
                  ? '실제 네트워크/IT 장비 대여 샘플'
                  : '실제 소모품 대여 샘플',
        ),
      );
    }

    // 유지보수 샘플 데이터(12개월, 모든 방문주기/점검형태 조합) 추가
    final List<String> visitCycles = [
      '미방문',
      '장애시 지원',
      '월',
      '격월',
      '분기',
      '반기',
      '년',
    ];
    final List<String> inspectionTypes = ['방문', '원격'];
    for (final visit in visitCycles) {
      for (final inspection in inspectionTypes) {
        addLicense(
          License(
            licenseKey: 'LIC-${DateTime.now().millisecondsSinceEpoch}-$visit-$inspection',
            productName: '12개월,$visit,$inspection',
            companyId: 1,
            purchaseDate: DateTime.now(),
            expiryDate: DateTime.now().add(const Duration(days: 365)),
            remark: '방문주기: $visit',
          ),
        );
      }
    }
    // 1번 유지보수 샘플 아이템 삭제
    deleteLicense(1);

    // 입고지 mock 데이터 추가
    addWarehouseLocation(
      WarehouseLocation(
        id: _warehouseLocationIdCounter,
        name: '당사',
        address: Address(
          zipCode: '01234',
          region: '서울특별시',
          detailAddress: '강남구 테헤란로 1',
        ),
        remark: '본사 전용 입고지',
      ),
    );
    addWarehouseLocation(
      WarehouseLocation(
        id: _warehouseLocationIdCounter,
        name: '서울 입고지',
        address: Address(
          zipCode: '04524',
          region: '서울특별시',
          detailAddress: '중구 퇴계로 100',
        ),
        remark: '본사 창고',
      ),
    );
    addWarehouseLocation(
      WarehouseLocation(
        id: _warehouseLocationIdCounter,
        name: '부산 입고지',
        address: Address(
          zipCode: '48942',
          region: '부산광역시',
          detailAddress: '중구 중앙대로 50',
        ),
        remark: '부산지점 창고',
      ),
    );
  }

  // 장비 입고 관련 메소드
  List<EquipmentIn> getAllEquipmentIns() {
    return _equipmentIns;
  }

  EquipmentIn? getEquipmentInById(int id) {
    try {
      return _equipmentIns.firstWhere((e) => e.id == id);
    } catch (e) {
      return null;
    }
  }

  void addEquipmentIn(EquipmentIn equipmentIn) {
    final newEquipmentIn = EquipmentIn(
      id: _equipmentInIdCounter++,
      equipment: equipmentIn.equipment,
      inDate: equipmentIn.inDate,
      status: equipmentIn.status,
      type: equipmentIn.type,
      warehouseLocation: equipmentIn.warehouseLocation,
      partnerCompany: equipmentIn.partnerCompany,
    );
    _equipmentIns.add(newEquipmentIn);
  }

  void updateEquipmentIn(EquipmentIn equipmentIn) {
    final index = _equipmentIns.indexWhere((e) => e.id == equipmentIn.id);
    if (index != -1) {
      _equipmentIns[index] = equipmentIn;
    }
  }

  void deleteEquipmentIn(int id) {
    _equipmentIns.removeWhere((e) => e.id == id);
  }

  // 장비 출고 관련 메소드
  List<EquipmentOut> getAllEquipmentOuts() {
    return _equipmentOuts;
  }

  EquipmentOut? getEquipmentOutById(int id) {
    try {
      return _equipmentOuts.firstWhere((e) => e.id == id);
    } catch (e) {
      return null;
    }
  }

  // 기존 입고 장비를 출고 상태로 변경
  void changeEquipmentStatus(int equipmentInId, EquipmentOut equipmentOut) {
    // 장비 상태 변경 시작: 입고 ID $equipmentInId

    // 입고된 장비를 찾습니다
    final index = _equipmentIns.indexWhere((e) => e.id == equipmentInId);
    if (index != -1) {
      // 장비를 찾음: ${_equipmentIns[index].equipment.name}

      // 입고 장비의 상태를 출고(O)로 변경
      final equipment = _equipmentIns[index].equipment;
      _equipmentIns[index] = EquipmentIn(
        id: _equipmentIns[index].id,
        equipment: equipment,
        inDate: _equipmentIns[index].inDate,
        status: 'O', // 상태를 출고로 변경
      );
      // 입고 장비 상태를 "O"로 변경: ID ${_equipmentIns[index].id}

      // 출고 정보 저장
      final newEquipmentOut = EquipmentOut(
        id: _equipmentOutIdCounter++,
        equipment: equipment,
        outDate: equipmentOut.outDate,
        status: equipmentOut.status,
        company: equipmentOut.company,
        manager: equipmentOut.manager,
        license: equipmentOut.license,
        returnDate: equipmentOut.returnDate,
        returnType: equipmentOut.returnType,
      );
      _equipmentOuts.add(newEquipmentOut);
      // 출고 정보 추가: ID ${newEquipmentOut.id}

      // 장비 상태 변경 완료
    } else {
      // 오류: ID $equipmentInId인 입고 장비를 찾을 수 없음
    }
  }

  void addEquipmentOut(EquipmentOut equipmentOut) {
    final newEquipmentOut = EquipmentOut(
      id: _equipmentOutIdCounter++,
      equipment: equipmentOut.equipment,
      outDate: equipmentOut.outDate,
      status: equipmentOut.status,
      company: equipmentOut.company,
      manager: equipmentOut.manager,
      license: equipmentOut.license,
      returnDate: equipmentOut.returnDate,
      returnType: equipmentOut.returnType,
    );
    _equipmentOuts.add(newEquipmentOut);
  }

  void updateEquipmentOut(EquipmentOut equipmentOut) {
    final index = _equipmentOuts.indexWhere((e) => e.id == equipmentOut.id);
    if (index != -1) {
      _equipmentOuts[index] = equipmentOut;
    }
  }

  void deleteEquipmentOut(int id) {
    _equipmentOuts.removeWhere((e) => e.id == id);
  }

  // 제조사명 목록 반환
  List<String> getAllManufacturers() {
    final manufacturers = <String>[];

    for (final equipment in _equipmentIns) {
      if (equipment.equipment.manufacturer.isNotEmpty &&
          !manufacturers.contains(equipment.equipment.manufacturer)) {
        manufacturers.add(equipment.equipment.manufacturer);
      }
    }

    for (final equipment in _equipmentOuts) {
      if (equipment.equipment.manufacturer.isNotEmpty &&
          !manufacturers.contains(equipment.equipment.manufacturer)) {
        manufacturers.add(equipment.equipment.manufacturer);
      }
    }

    // 기본 제조사 추가 (초기 데이터가 없을 경우)
    manufacturers.addAll([
      '삼성',
      '삼성전자',
      '삼성디스플레이',
      'LG',
      'LG전자',
      'LG디스플레이',
      'Apple',
      'HP',
      'Dell',
      'Lenovo',
      'Asus',
      'Acer',
      '한성컴퓨터',
      '기가바이트',
      'MSI',
      'Intel',
      'AMD',
    ]);

    return manufacturers..sort();
  }

  // 모든 장비명 가져오기
  List<String> getAllEquipmentNames() {
    final equipmentNames = <String>[];

    for (final equipment in _equipmentIns) {
      if (equipment.equipment.name.isNotEmpty &&
          !equipmentNames.contains(equipment.equipment.name)) {
        equipmentNames.add(equipment.equipment.name);
      }
    }

    for (final equipment in _equipmentOuts) {
      if (equipment.equipment.name.isNotEmpty &&
          !equipmentNames.contains(equipment.equipment.name)) {
        equipmentNames.add(equipment.equipment.name);
      }
    }

    return equipmentNames..sort();
  }

  // 회사명 목록 가져오기
  List<String> getAllCompanyNames() {
    return _companies.map((company) => company.name).toList();
  }

  // 지점명 목록 가져오기
  List<String> getAllBranchNames() {
    final branchNames = <String>[];

    for (final company in _companies) {
      if (company.branches != null) {
        for (final branch in company.branches!) {
          if (branch.name.isNotEmpty && !branchNames.contains(branch.name)) {
            branchNames.add(branch.name);
          }
        }
      }
    }

    return branchNames..sort();
  }

  // 회사 관련 메소드
  List<Company> getAllCompanies() {
    return List.from(_companies);
  }

  Company? getCompanyById(int id) {
    try {
      return _companies.firstWhere((company) => company.id == id);
    } catch (e) {
      return null;
    }
  }

  // 이름으로 회사를 찾는 메서드 추가
  Company? findCompanyByName(String name) {
    if (name.isEmpty) return null;

    try {
      return _companies.firstWhere(
        (company) => company.name.toLowerCase() == name.toLowerCase(),
      );
    } catch (e) {
      return null;
    }
  }

  void addCompany(Company company) {
    final newCompany = Company(
      id: _companyIdCounter++,
      name: company.name,
      address: company.address,
      contactName: company.contactName,
      contactPosition: company.contactPosition,
      contactPhone: company.contactPhone,
      contactEmail: company.contactEmail,
      companyTypes: company.companyTypes,
      remark: company.remark,
      branches:
          company.branches?.map((branch) {
            return Branch(
              id:
                  branch.id ??
                  (_companyIdCounter * 100 +
                      (company.branches?.indexOf(branch) ?? 0)),
              companyId: _companyIdCounter - 1,
              name: branch.name,
              address: branch.address,
              contactName: branch.contactName,
              contactPosition: branch.contactPosition,
              contactPhone: branch.contactPhone,
              contactEmail: branch.contactEmail,
              remark: branch.remark,
            );
          }).toList(),
    );
    _companies.add(newCompany);
  }

  void updateCompany(Company company) {
    final index = _companies.indexWhere((c) => c.id == company.id);
    if (index != -1) {
      _companies[index] = company;
    }
  }
  
  void updateBranch(int companyId, Branch branch) {
    final companyIndex = _companies.indexWhere((c) => c.id == companyId);
    if (companyIndex != -1) {
      final company = _companies[companyIndex];
      if (company.branches != null) {
        final branchIndex = company.branches!.indexWhere((b) => b.id == branch.id);
        if (branchIndex != -1) {
          company.branches![branchIndex] = branch;
        }
      }
    }
  }

  void deleteCompany(int id) {
    _companies.removeWhere((c) => c.id == id);
  }

  // 사용자 관련 메소드
  List<User> getAllUsers() {
    return _users;
  }

  User? getUserById(int id) {
    try {
      return _users.firstWhere((u) => u.id == id);
    } catch (e) {
      return null;
    }
  }

  void addUser(User user) {
    final newUser = User(
      id: _userIdCounter++,
      companyId: user.companyId,
      branchId: user.branchId,
      name: user.name,
      role: user.role,
      position: user.position,
      email: user.email,
      phoneNumbers: user.phoneNumbers,
    );
    _users.add(newUser);
  }

  void updateUser(User user) {
    final index = _users.indexWhere((u) => u.id == user.id);
    if (index != -1) {
      _users[index] = user;
    }
  }

  void deleteUser(int id) {
    _users.removeWhere((u) => u.id == id);
  }

  // 라이센스 관련 메소드
  List<License> getAllLicenses() {
    return _licenses;
  }

  License? getLicenseById(int id) {
    try {
      return _licenses.firstWhere((l) => l.id == id);
    } catch (e) {
      return null;
    }
  }

  void addLicense(License license) {
    final newLicense = License(
      id: _licenseIdCounter++,
      licenseKey: license.licenseKey,
      productName: license.productName,
      vendor: license.vendor,
      licenseType: license.licenseType,
      userCount: license.userCount,
      purchaseDate: license.purchaseDate,
      expiryDate: license.expiryDate,
      purchasePrice: license.purchasePrice,
      companyId: license.companyId,
      branchId: license.branchId,
      assignedUserId: license.assignedUserId,
      remark: license.remark,
      isActive: license.isActive,
    );
    _licenses.add(newLicense);
  }

  void updateLicense(License license) {
    final index = _licenses.indexWhere((l) => l.id == license.id);
    if (index != -1) {
      _licenses[index] = license;
    }
  }

  void deleteLicense(int id) {
    _licenses.removeWhere((l) => l.id == id);
  }

  // 장비 통합 관련 메소드
  List<UnifiedEquipment> getAllEquipments() {
    final List<UnifiedEquipment> allEquipments = [];

    // 입고 장비를 통합 목록에 추가 (출고 상태가 아닌 장비만)
    for (var equipmentIn in _equipmentIns) {
      // 상태가 'O'(출고)가 아닌 장비만 목록에 포함
      if (equipmentIn.status != 'O') {
        allEquipments.add(
          UnifiedEquipment.fromEquipmentIn(
            equipmentIn.id,
            equipmentIn.equipment,
            equipmentIn.inDate,
            equipmentIn.status,
            type: equipmentIn.type,
          ),
        );
      }
    }

    // 출고 장비를 통합 목록에 추가
    for (var equipmentOut in _equipmentOuts) {
      allEquipments.add(
        UnifiedEquipment(
          id: equipmentOut.id,
          equipment: equipmentOut.equipment,
          date: equipmentOut.outDate,
          status: equipmentOut.status,
        ),
      );
    }

    // 날짜 기준 내림차순 정렬 (최신 항목이 먼저 표시)
    allEquipments.sort((a, b) => b.date.compareTo(a.date));

    return allEquipments;
  }

  // ID로 통합 장비 조회
  UnifiedEquipment? getEquipmentById(int id, String status) {
    // 상태가 입고인 경우
    if (status == 'I') {
      final equipmentIn = getEquipmentInById(id);
      if (equipmentIn != null) {
        return UnifiedEquipment(
          id: equipmentIn.id,
          equipment: equipmentIn.equipment,
          date: equipmentIn.inDate,
          status: equipmentIn.status,
        );
      }
    }
    // 상태가 출고인 경우
    else if (status == 'O') {
      final equipmentOut = getEquipmentOutById(id);
      if (equipmentOut != null) {
        return UnifiedEquipment(
          id: equipmentOut.id,
          equipment: equipmentOut.equipment,
          date: equipmentOut.outDate,
          status: equipmentOut.status,
        );
      }
    }
    return null;
  }

  // 통합 장비 삭제
  void deleteEquipment(int id, String status) {
    if (status == 'I') {
      deleteEquipmentIn(id);
    } else if (status == 'O') {
      deleteEquipmentOut(id);
    }
  }

  // 입고지 전체 조회
  List<WarehouseLocation> getAllWarehouseLocations() {
    return _warehouseLocations;
  }

  // 입고지 ID로 조회
  WarehouseLocation? getWarehouseLocationById(int id) {
    try {
      return _warehouseLocations.firstWhere((w) => w.id == id);
    } catch (e) {
      return null;
    }
  }

  // 입고지 추가
  void addWarehouseLocation(WarehouseLocation location) {
    final newLocation = WarehouseLocation(
      id: _warehouseLocationIdCounter++,
      name: location.name,
      address: location.address,
      remark: location.remark,
    );
    _warehouseLocations.add(newLocation);
  }

  // 입고지 수정
  void updateWarehouseLocation(WarehouseLocation location) {
    final index = _warehouseLocations.indexWhere((w) => w.id == location.id);
    if (index != -1) {
      _warehouseLocations[index] = location;
    }
  }

  // 입고지 삭제
  void deleteWarehouseLocation(int id) {
    _warehouseLocations.removeWhere((w) => w.id == id);
  }

  // 카테고리명 목록 반환
  List<String> getAllCategories() {
    final categories = <String>[];
    for (final equipment in _equipmentIns) {
      if (equipment.equipment.category.isNotEmpty &&
          !categories.contains(equipment.equipment.category)) {
        categories.add(equipment.equipment.category);
      }
    }
    for (final equipment in _equipmentOuts) {
      if (equipment.equipment.category.isNotEmpty &&
          !categories.contains(equipment.equipment.category)) {
        categories.add(equipment.equipment.category);
      }
    }
    return categories..sort();
  }

  // 서브카테고리명 목록 반환
  List<String> getAllSubCategories() {
    final subCategories = <String>[];
    for (final equipment in _equipmentIns) {
      if (equipment.equipment.subCategory.isNotEmpty &&
          !subCategories.contains(equipment.equipment.subCategory)) {
        subCategories.add(equipment.equipment.subCategory);
      }
    }
    for (final equipment in _equipmentOuts) {
      if (equipment.equipment.subCategory.isNotEmpty &&
          !subCategories.contains(equipment.equipment.subCategory)) {
        subCategories.add(equipment.equipment.subCategory);
      }
    }
    return subCategories..sort();
  }

  // 서브서브카테고리명 목록 반환
  List<String> getAllSubSubCategories() {
    final subSubCategories = <String>[];
    for (final equipment in _equipmentIns) {
      if (equipment.equipment.subSubCategory.isNotEmpty &&
          !subSubCategories.contains(equipment.equipment.subSubCategory)) {
        subSubCategories.add(equipment.equipment.subSubCategory);
      }
    }
    for (final equipment in _equipmentOuts) {
      if (equipment.equipment.subSubCategory.isNotEmpty &&
          !subSubCategories.contains(equipment.equipment.subSubCategory)) {
        subSubCategories.add(equipment.equipment.subSubCategory);
      }
    }
    return subSubCategories..sort();
  }
}
