import 'package:flutter/foundation.dart';
import 'package:injectable/injectable.dart';
import 'package:superport/core/errors/exceptions.dart';
import 'package:superport/core/errors/failures.dart';
import 'package:superport/data/datasources/remote/company_remote_datasource.dart';
import 'package:superport/data/models/company/company_dto.dart';
import 'package:superport/data/models/company/company_list_dto.dart';
import 'package:superport/data/models/company/branch_dto.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/address_model.dart';

@lazySingleton
class CompanyService {
  final CompanyRemoteDataSource _remoteDataSource;
  
  CompanyService(this._remoteDataSource);

  // 회사 목록 조회
  Future<List<Company>> getCompanies({
    int page = 1,
    int perPage = 20,
    String? search,
    bool? isActive,
  }) async {
    try {
      final response = await _remoteDataSource.getCompanies(
        page: page,
        perPage: perPage,
        search: search,
        isActive: isActive,
      );

      return response.items.map((dto) => _convertListDtoToCompany(dto)).toList();
    } on ApiException catch (e) {
      debugPrint('[CompanyService] ApiException: ${e.message}');
      throw ServerFailure(message: e.message);
    } catch (e, stackTrace) {
      debugPrint('[CompanyService] Error loading companies: $e');
      debugPrint('[CompanyService] Stack trace: $stackTrace');
      throw ServerFailure(message: 'Failed to fetch company list: $e');
    }
  }

  // 회사 생성
  Future<Company> createCompany(Company company) async {
    try {
      final request = CreateCompanyRequest(
        name: company.name,
        address: company.address.toString(),
        contactName: company.contactName ?? '',
        contactPosition: company.contactPosition ?? '',
        contactPhone: company.contactPhone ?? '',
        contactEmail: company.contactEmail ?? '',
        companyTypes: company.companyTypes.map((e) => e.toString().split('.').last).toList(),
        remark: company.remark,
      );

      debugPrint('[CompanyService] Creating company with request: ${request.toJson()}');
      final response = await _remoteDataSource.createCompany(request);
      debugPrint('[CompanyService] Company created with ID: ${response.id}');
      return _convertResponseToCompany(response);
    } on ApiException catch (e) {
      debugPrint('[CompanyService] ApiException during company creation: ${e.message}');
      throw ServerFailure(message: e.message);
    } catch (e, stackTrace) {
      debugPrint('[CompanyService] Unexpected error during company creation: $e');
      debugPrint('[CompanyService] Stack trace: $stackTrace');
      throw ServerFailure(message: 'Failed to create company: $e');
    }
  }

  // 회사 상세 조회
  Future<Company> getCompanyDetail(int id) async {
    try {
      final response = await _remoteDataSource.getCompanyDetail(id);
      return _convertResponseToCompany(response);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch company detail: $e');
    }
  }

  // 회사와 지점 정보 함께 조회
  Future<Company> getCompanyWithBranches(int id) async {
    try {
      final response = await _remoteDataSource.getCompanyWithBranches(id);
      final company = _convertResponseToCompany(response.company);
      final branches = response.branches.map((dto) => _convertBranchDtoToBranch(dto)).toList();
      
      return company.copyWith(branches: branches);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch company with branches: $e');
    }
  }

  // 회사 수정
  Future<Company> updateCompany(int id, Company company) async {
    try {
      final request = UpdateCompanyRequest(
        name: company.name,
        address: company.address.toString(),
        contactName: company.contactName,
        contactPosition: company.contactPosition,
        contactPhone: company.contactPhone,
        contactEmail: company.contactEmail,
        companyTypes: company.companyTypes.map((e) => e.toString().split('.').last).toList(),
        remark: company.remark,
      );

      final response = await _remoteDataSource.updateCompany(id, request);
      return _convertResponseToCompany(response);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to update company: $e');
    }
  }

  // 회사 삭제
  Future<void> deleteCompany(int id) async {
    try {
      await _remoteDataSource.deleteCompany(id);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to delete company: $e');
    }
  }

  // 회사명 목록 조회 (드롭다운용)
  Future<List<Map<String, dynamic>>> getCompanyNames() async {
    try {
      final dtoList = await _remoteDataSource.getCompanyNames();
      return dtoList.map((dto) => {
        'id': dto.id,
        'name': dto.name,
      }).toList();
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch company names: $e');
    }
  }

  // 지점 관련 메서드들
  Future<Branch> createBranch(int companyId, Branch branch) async {
    try {
      final request = CreateBranchRequest(
        branchName: branch.name,
        address: branch.address.toString(),
        phone: branch.contactPhone ?? '',
        managerName: branch.contactName,
        managerPhone: branch.contactPhone,
        remark: branch.remark,
      );

      final response = await _remoteDataSource.createBranch(companyId, request);
      return _convertBranchResponseToBranch(response);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to create branch: $e');
    }
  }

  Future<Branch> getBranchDetail(int companyId, int branchId) async {
    try {
      final response = await _remoteDataSource.getBranchDetail(companyId, branchId);
      return _convertBranchResponseToBranch(response);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch branch detail: $e');
    }
  }

  Future<Branch> updateBranch(int companyId, int branchId, Branch branch) async {
    try {
      final request = UpdateBranchRequest(
        branchName: branch.name,
        address: branch.address.toString(),
        phone: branch.contactPhone,
        managerName: branch.contactName,
        managerPhone: branch.contactPhone,
        remark: branch.remark,
      );

      final response = await _remoteDataSource.updateBranch(companyId, branchId, request);
      return _convertBranchResponseToBranch(response);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to update branch: $e');
    }
  }

  Future<void> deleteBranch(int companyId, int branchId) async {
    try {
      await _remoteDataSource.deleteBranch(companyId, branchId);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to delete branch: $e');
    }
  }

  Future<List<Branch>> getCompanyBranches(int companyId) async {
    try {
      final dtoList = await _remoteDataSource.getCompanyBranches(companyId);
      return dtoList.map((dto) => _convertBranchDtoToBranch(dto)).toList();
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch company branches: $e');
    }
  }

  // 회사-지점 전체 정보 조회
  Future<List<CompanyWithBranches>> getCompaniesWithBranches() async {
    try {
      return await _remoteDataSource.getCompaniesWithBranches();
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to fetch companies with branches: $e');
    }
  }

  // 회사명 중복 확인
  Future<bool> checkDuplicateCompany(String name) async {
    try {
      return await _remoteDataSource.checkDuplicateCompany(name);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to check duplicate: $e');
    }
  }

  // 회사 검색
  Future<List<Company>> searchCompanies(String query) async {
    try {
      final dtoList = await _remoteDataSource.searchCompanies(query);
      return dtoList.map((dto) => _convertListDtoToCompany(dto)).toList();
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to search companies: $e');
    }
  }

  // 회사 활성 상태 변경
  Future<void> updateCompanyStatus(int id, bool isActive) async {
    try {
      await _remoteDataSource.updateCompanyStatus(id, isActive);
    } on ApiException catch (e) {
      throw ServerFailure(message: e.message);
    } catch (e) {
      throw ServerFailure(message: 'Failed to update company status: $e');
    }
  }

  // 변환 헬퍼 메서드들
  Company _convertListDtoToCompany(CompanyListDto dto) {
    return Company(
      id: dto.id,
      name: dto.name,
      address: Address.fromFullAddress(dto.address),
      contactName: dto.contactName,
      contactPhone: dto.contactPhone,
      companyTypes: [CompanyType.customer], // 기본값, 실제로는 API에서 받아와야 함
      branches: [], // branches는 빈 배열로 초기화
    );
  }

  Company _convertResponseToCompany(CompanyResponse dto) {
    final companyTypes = dto.companyTypes.map((typeStr) {
      if (typeStr.contains('partner')) return CompanyType.partner;
      return CompanyType.customer;
    }).toList();

    return Company(
      id: dto.id,
      name: dto.name,
      address: Address.fromFullAddress(dto.address),
      contactName: dto.contactName,
      contactPosition: dto.contactPosition,
      contactPhone: dto.contactPhone,
      contactEmail: dto.contactEmail,
      companyTypes: companyTypes.isEmpty ? [CompanyType.customer] : companyTypes,
      remark: dto.remark,
      branches: [], // branches는 빈 배열로 초기화
    );
  }

  Branch _convertBranchDtoToBranch(BranchListDto dto) {
    return Branch(
      id: dto.id,
      companyId: dto.companyId,
      name: dto.branchName,
      address: Address.fromFullAddress(dto.address),
      contactName: dto.managerName,
      contactPhone: dto.phone,
    );
  }

  Branch _convertBranchResponseToBranch(BranchResponse dto) {
    return Branch(
      id: dto.id,
      companyId: dto.companyId,
      name: dto.branchName,
      address: Address.fromFullAddress(dto.address),
      contactName: dto.managerName,
      contactPhone: dto.phone,
      remark: dto.remark,
    );
  }
}

// Company 모델에 copyWith 메서드가 없다면 extension으로 추가
extension CompanyExtension on Company {
  Company copyWith({
    int? id,
    String? name,
    Address? address,
    String? contactName,
    String? contactPosition,
    String? contactPhone,
    String? contactEmail,
    List<Branch>? branches,
    List<CompanyType>? companyTypes,
    String? remark,
  }) {
    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,
    );
  }
}