/// 지점 관리 컨트롤러 (입력/수정 통합)
///
/// 지점 생성 및 수정 화면의 비즈니스 로직을 담당하는 통합 컨트롤러 클래스
/// 주요 기능:
/// - 본사 목록 조회 및 관리
/// - 지점 정보 입력/수정 관리
/// - 지점 생성/수정 요청
/// - 폼 유효성 검증
/// - 수정 모드에서 기존 데이터 로드
library;
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:superport/models/address_model.dart';
import 'package:superport/models/company_model.dart';
import 'package:superport/models/company_item_model.dart';
import 'package:superport/services/company_service.dart';
import 'package:superport/core/errors/failures.dart';
import 'package:superport/utils/phone_utils.dart';
import 'dart:async';

/// 지점 컨트롤러 - 본사 선택 및 지점 정보 입력/수정 관리
class BranchController extends ChangeNotifier {
  final CompanyService _companyService = GetIt.instance<CompanyService>();
  
  // 수정 모드 관련
  final int? branchId; // 수정할 지점 ID (null이면 생성 모드)
  final String? parentCompanyName; // 본사명 (수정 모드에서 표시용)
  bool get isEditMode => branchId != null;
  
  // 원본 데이터 (변경 감지용)
  Company? _originalBranch;
  Company? get originalBranch => _originalBranch;
  
  // 본사 목록 관련
  List<CompanyItem> _headquartersList = [];
  List<CompanyItem> get headquartersList => _headquartersList;
  
  int? _selectedHeadquarterId;
  int? get selectedHeadquarterId => _selectedHeadquarterId;
  
  String? _selectedHeadquarterName;
  String? get selectedHeadquarterName => _selectedHeadquarterName;
  
  // 로딩 상태
  bool _isLoading = false;
  bool get isLoading => _isLoading;
  
  bool _isLoadingHeadquarters = false;
  bool get isLoadingHeadquarters => _isLoadingHeadquarters;
  
  bool _isSaving = false;
  bool get isSaving => _isSaving;
  
  // 에러 메시지
  String? _errorMessage;
  String? get errorMessage => _errorMessage;
  
  // 폼 컨트롤러들
  final GlobalKey<FormState> formKey = GlobalKey<FormState>();
  final TextEditingController nameController = TextEditingController();
  final TextEditingController contactNameController = TextEditingController();
  final TextEditingController contactPositionController = TextEditingController();
  final TextEditingController contactPhoneController = TextEditingController();
  final TextEditingController contactEmailController = TextEditingController();
  final TextEditingController remarkController = TextEditingController();
  
  // 주소 관련
  Address branchAddress = const Address();
  final TextEditingController addressController = TextEditingController();
  
  // 전화번호 관련
  String _selectedPhonePrefix = '010';
  String get selectedPhonePrefix => _selectedPhonePrefix;
  final TextEditingController phoneNumberController = TextEditingController();
  final List<String> _phonePrefixes = PhoneUtils.getCommonPhonePrefixes();
  List<String> get phonePrefixes => _phonePrefixes;
  
  BranchController({
    this.branchId, // 수정 모드: 지점 ID, 생성 모드: null
    this.parentCompanyName, // 수정 모드: 본사명 (표시용)
  }) {
    if (!isEditMode) {
      // 생성 모드: 본사 목록 로드
      _loadHeadquarters();
    } else {
      // 수정 모드: 지점 데이터 로드 및 본사 목록도 로드
      _loadHeadquarters();
      _loadBranchData();
    }
  }
  
  /// 지점 데이터 로드 (수정 모드에서만 사용)
  Future<void> _loadBranchData() async {
    if (!isEditMode || branchId == null) return;
    
    _isLoading = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      final company = await _companyService.getCompanyDetail(branchId!);
      _originalBranch = company;
      _populateFormWithBranchData(company);
    } catch (e) {
      _errorMessage = '지점 정보를 불러오는 중 오류가 발생했습니다: $e';
    } finally {
      _isLoading = false;
      notifyListeners();
    }
  }

  /// 본사 목록 로드 (전체 본사 목록 로드 - 55개 전체)
  Future<void> _loadHeadquarters() async {
    _isLoadingHeadquarters = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      final result = await _companyService.getAllHeadquarters();
      result.fold(
        (failure) {
          _errorMessage = _getFailureMessage(failure);
        },
        (headquarters) {
          _headquartersList = headquarters;
        },
      );
    } catch (e) {
      _errorMessage = '본사 목록을 불러오는 중 오류가 발생했습니다: $e';
    } finally {
      _isLoadingHeadquarters = false;
      notifyListeners();
    }
  }
  
  /// 폼에 지점 데이터 설정 (수정 모드에서만 사용)
  void _populateFormWithBranchData(Company company) {
    nameController.text = company.name;
    addressController.text = company.address.detailAddress ?? '';
    contactNameController.text = company.contactName ?? '';
    contactPositionController.text = company.contactPosition ?? '';
    contactEmailController.text = company.contactEmail ?? '';
    remarkController.text = company.remark ?? '';
    
    // 전화번호 파싱 (간단한 로직으로 구현)
    final phoneNumber = company.contactPhone ?? '';
    if (phoneNumber.isNotEmpty) {
      final parts = _parsePhoneNumber(phoneNumber);
      _selectedPhonePrefix = parts['prefix'] ?? '010';
      phoneNumberController.text = parts['number'] ?? '';
    }
    
    // 본사 ID 설정
    if (company.parentCompanyId != null) {
      _selectedHeadquarterId = company.parentCompanyId;
      // 본사명 찾기
      final headquarters = _headquartersList
          .where((h) => h.id == company.parentCompanyId)
          .firstOrNull;
      _selectedHeadquarterName = headquarters?.name ?? parentCompanyName;
    }
    
    notifyListeners();
  }

  /// 본사 선택
  void selectHeadquarters(int headquarterId, String headquarterName) {
    _selectedHeadquarterId = headquarterId;
    _selectedHeadquarterName = headquarterName;
    notifyListeners();
  }
  
  /// 전화번호 접두사 선택
  void selectPhonePrefix(String prefix) {
    _selectedPhonePrefix = prefix;
    notifyListeners();
  }
  
  /// 주소 업데이트
  void updateBranchAddress(Address address) {
    branchAddress = address;
    notifyListeners();
  }
  
  /// 지점 저장 (생성 또는 수정)
  Future<bool> saveBranch() async {
    if (!formKey.currentState!.validate()) {
      return false;
    }
    
    if (_selectedHeadquarterId == null) {
      _errorMessage = '본사를 선택해주세요';
      notifyListeners();
      return false;
    }
    
    _isSaving = true;
    _errorMessage = null;
    notifyListeners();
    
    try {
      // 전화번호 합치기
      final fullPhoneNumber = PhoneUtils.getFullPhoneNumber(
        _selectedPhonePrefix, 
        phoneNumberController.text
      );
      contactPhoneController.text = fullPhoneNumber;
      
      // 주소 업데이트
      updateBranchAddress(Address.fromFullAddress(addressController.text));
      
      if (isEditMode && _originalBranch != null) {
        // 수정 모드: 기존 지점 정보 업데이트
        final updatedBranch = _originalBranch!.copyWith(
          name: nameController.text.trim(),
          address: branchAddress,
          contactName: contactNameController.text.trim(),
          contactPosition: contactPositionController.text.trim(),
          contactPhone: fullPhoneNumber,
          contactEmail: contactEmailController.text.trim(),
          remark: remarkController.text.trim(),
          parentCompanyId: _selectedHeadquarterId,
          updatedAt: DateTime.now(),
        );
        
        final updatedCompany = await _companyService.updateCompany(branchId!, updatedBranch);
        _originalBranch = updatedCompany;
      } else {
        // 생성 모드: 새 지점 생성
        final branchCompany = Company(
          id: 0, // 새 지점이므로 0
          name: nameController.text.trim(),
          address: branchAddress,
          contactName: contactNameController.text.trim(),
          contactPosition: contactPositionController.text.trim(),
          contactPhone: fullPhoneNumber,
          contactEmail: contactEmailController.text.trim(),
          remark: remarkController.text.trim(),
          parentCompanyId: _selectedHeadquarterId, // 본사 ID 설정
          companyTypes: [CompanyType.customer], // 기본값
          isPartner: false,
          isCustomer: true,
          createdAt: DateTime.now(),
          updatedAt: DateTime.now(),
          isActive: true,
        );
        
        await _companyService.createCompany(branchCompany);
      }
      
      return true;
    } catch (e) {
      _errorMessage = '지점 저장 중 오류가 발생했습니다: $e';
      return false;
    } finally {
      _isSaving = false;
      notifyListeners();
    }
  }
  
  /// 본사 목록 새로고침
  Future<void> refreshHeadquarters() async {
    await _loadHeadquarters();
  }
  
  /// 변경사항 확인 (수정 모드에서만 사용)
  bool hasChanges() {
    if (!isEditMode || _originalBranch == null) return false;
    
    final currentAddress = Address.fromFullAddress(addressController.text);
    final currentFullPhone = PhoneUtils.getFullPhoneNumber(
      _selectedPhonePrefix, 
      phoneNumberController.text
    );
    
    return nameController.text.trim() != _originalBranch!.name ||
           currentAddress.detailAddress != (_originalBranch!.address.detailAddress ?? '') ||
           contactNameController.text.trim() != (_originalBranch!.contactName ?? '') ||
           contactPositionController.text.trim() != (_originalBranch!.contactPosition ?? '') ||
           currentFullPhone != (_originalBranch!.contactPhone ?? '') ||
           contactEmailController.text.trim() != (_originalBranch!.contactEmail ?? '') ||
           remarkController.text.trim() != (_originalBranch!.remark ?? '') ||
           _selectedHeadquarterId != _originalBranch!.parentCompanyId;
  }
  
  /// 폼 초기화
  void resetForm() {
    nameController.clear();
    contactNameController.clear();
    contactPositionController.clear();
    phoneNumberController.clear();
    contactEmailController.clear();
    remarkController.clear();
    addressController.clear();
    
    _selectedHeadquarterId = null;
    _selectedHeadquarterName = null;
    _selectedPhonePrefix = '010';
    branchAddress = const Address();
    _errorMessage = null;
    
    notifyListeners();
  }
  
  /// 전화번호 파싱 헬퍼 메서드
  Map<String, String> _parsePhoneNumber(String phoneNumber) {
    final cleaned = phoneNumber.replaceAll(RegExp(r'[^\d]'), '');
    
    // 휴대폰 번호 (010, 011, 016, 017, 018, 019, 070)
    if (cleaned.startsWith('010') || cleaned.startsWith('011') || 
        cleaned.startsWith('016') || cleaned.startsWith('017') || 
        cleaned.startsWith('018') || cleaned.startsWith('019') || 
        cleaned.startsWith('070')) {
      final prefix = cleaned.substring(0, 3);
      final number = cleaned.length > 3 ? cleaned.substring(3) : '';
      final formatted = number.length > 4 
          ? '${number.substring(0, number.length - 4)}-${number.substring(number.length - 4)}'
          : number;
      return {'prefix': prefix, 'number': formatted};
    }
    
    // 서울 지역번호 (02)
    if (cleaned.startsWith('02')) {
      final prefix = '02';
      final number = cleaned.length > 2 ? cleaned.substring(2) : '';
      final formatted = number.length > 4 
          ? '${number.substring(0, number.length - 4)}-${number.substring(number.length - 4)}'
          : number;
      return {'prefix': prefix, 'number': formatted};
    }
    
    // 기타 지역번호 (031, 032, 033 등)
    if (cleaned.length >= 3 && cleaned.startsWith('0')) {
      final prefix = cleaned.substring(0, 3);
      final number = cleaned.length > 3 ? cleaned.substring(3) : '';
      final formatted = number.length > 4 
          ? '${number.substring(0, number.length - 4)}-${number.substring(number.length - 4)}'
          : number;
      return {'prefix': prefix, 'number': formatted};
    }
    
    // 파싱 실패 시 기본값
    return {'prefix': '010', 'number': phoneNumber};
  }

  /// Failure 메시지 변환
  String _getFailureMessage(Failure failure) {
    switch (failure.runtimeType) {
      case ServerFailure:
        return '서버 오류가 발생했습니다';
      case NetworkFailure:
        return '네트워크 연결을 확인해주세요';
      case CacheFailure:
        return '데이터 저장 중 오류가 발생했습니다';
      default:
        return failure.message ?? '알 수 없는 오류가 발생했습니다';
    }
  }
  
  @override
  void dispose() {
    nameController.dispose();
    contactNameController.dispose();
    contactPositionController.dispose();
    contactPhoneController.dispose();
    contactEmailController.dispose();
    remarkController.dispose();
    addressController.dispose();
    phoneNumberController.dispose();
    super.dispose();
  }
}