"""
작성계약(가공계약) 탐지 스크립트
- 보험계약 데이터 CSV 파일을 분석하여 작성계약 의심 패턴을 탐지합니다.
- ChatGPT와 토론하여 도출한 탐지 논리를 코드로 구현한 결과물입니다.
"""

import sys
import io
import os

import pandas as pd
from collections import Counter

# ========================================
# 출력 설정: 콘솔 + 파일 동시 저장
# ========================================
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
OUTPUT_PATH = os.path.join(BASE_DIR, "작성계약_탐지결과.txt")

class TeeWriter:
    def __init__(self, file, stdout):
        self.file = file
        self.stdout = stdout
    def write(self, text):
        self.stdout.write(text)
        self.file.write(text)
    def flush(self):
        self.stdout.flush()
        self.file.flush()

_original_stdout = sys.stdout
try:
    _original_stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
except:
    pass
_output_file = open(OUTPUT_PATH, 'w', encoding='utf-8')
sys.stdout = TeeWriter(_output_file, _original_stdout)

# ========================================
# 데이터 로드
# ========================================
df = pd.read_csv(os.path.join(BASE_DIR, "보험계약_데이터.csv"), encoding="utf-8-sig")
df["계약일"] = pd.to_datetime(df["계약일"])
df["계약일_일"] = df["계약일"].dt.day

print("=" * 80)
print("작성계약(가공계약) 탐지 분석 보고서")
print("=" * 80)
print(f"분석 대상 기간: {df['계약일'].min().date()} ~ {df['계약일'].max().date()}")
print(f"총 계약 건수: {len(df)}건")
print(f"총 월보험료: {df['월보험료'].sum():,.0f}원")
print(f"지점 수: {df['지점'].nunique()}개")
print()

# ========================================
# 탐지 1: 동일 계약자 다수 계약 (모집인 상이)
# ========================================
print("■ 탐지 1: 동일 계약자 다수 계약 (모집인 상이)")
print("-" * 60)

# 계약자별 계약 건수 집계
contractor_counts = df.groupby("계약자").agg(
    계약건수=("번호", "count"),
    모집인수=("모집인", "nunique"),
    모집인목록=("모집인", lambda x: ", ".join(sorted(x.unique()))),
    지점=("지점", "first"),
    총월보험료=("월보험료", "sum"),
    계약기간=("계약일", lambda x: f"{x.min().date()} ~ {x.max().date()}"),
    기간일수=("계약일", lambda x: (x.max() - x.min()).days),
    실효건수=("계약상태", lambda x: sum("실효" in str(s) for s in x)),
).reset_index()

# 2건 이상 계약자 필터
multi_contract = contractor_counts[contractor_counts["계약건수"] >= 2].sort_values(
    "계약건수", ascending=False
)

print(f"\n동일 계약자 2건 이상: {len(multi_contract)}명")

for _, row in multi_contract.iterrows():
    # 의심도 판정
    risk_factors = []
    if row["모집인수"] > 1:
        risk_factors.append(f"모집인 {row['모집인수']}명 상이")
    if row["기간일수"] <= 7:
        risk_factors.append(f"단기집중({row['기간일수']}일)")
    if row["실효건수"] > 0:
        risk_factors.append(f"실효 {row['실효건수']}건")

    risk_level = "★★★ 고위험" if len(risk_factors) >= 3 else "★★ 중위험" if len(risk_factors) >= 2 else "★ 저위험"

    print(f"\n  [{risk_level}] {row['계약자']} ({row['지점']})")
    print(f"    계약 {row['계약건수']}건 | 모집인: {row['모집인목록']}")
    print(f"    기간: {row['계약기간']} | 총 월보험료: {row['총월보험료']:,.0f}원")
    if risk_factors:
        print(f"    의심 사유: {' / '.join(risk_factors)}")

print()

# ========================================
# 탐지 2: 동일 주소 계약자 클러스터
# ========================================
print("■ 탐지 2: 동일 주소 계약자 클러스터 (지점장 관계자 의심)")
print("-" * 60)

# 주소별 계약자 그룹핑
address_groups = df.groupby("계약자주소").agg(
    계약자수=("계약자", "nunique"),
    계약자목록=("계약자", lambda x: ", ".join(sorted(x.unique()))),
    계약건수=("번호", "count"),
    모집인수=("모집인", "nunique"),
    지점=("지점", "first"),
    지점장=("지점장", "first"),
).reset_index()

# 동일 주소에 2명 이상 계약자
address_cluster = address_groups[address_groups["계약자수"] >= 2].sort_values(
    "계약자수", ascending=False
)

print(f"\n동일 주소 2명 이상 계약자 클러스터: {len(address_cluster)}건")

for _, row in address_cluster.iterrows():
    print(f"\n  주소: {row['계약자주소']}")
    print(f"  계약자 {row['계약자수']}명: {row['계약자목록']}")
    print(f"  계약 {row['계약건수']}건 | 모집인 {row['모집인수']}명 | {row['지점']} (지점장: {row['지점장']})")

print()

# ========================================
# 탐지 3: 유사 연락처 패턴
# ========================================
print("■ 탐지 3: 유사 연락처 패턴")
print("-" * 60)

# 연락처 앞 8자리 기준 그룹핑
df["전화앞8자리"] = df["계약자전화"].str[:11]  # 010-XXXX까지
phone_groups = df.groupby("전화앞8자리").agg(
    계약자수=("계약자", "nunique"),
    계약자목록=("계약자", lambda x: ", ".join(sorted(x.unique()))),
    전화목록=("계약자전화", lambda x: ", ".join(sorted(x.unique()))),
    지점=("지점", "first"),
).reset_index()

# 유사 번호 그룹 (같은 접두어로 2명 이상)
# 더 정교한 분석: 뒷 4자리만 다른 패턴
df["전화앞7자리"] = df["계약자전화"].str[:8]  # 010-XXXX
phone_prefix_groups = df.groupby("전화앞7자리").agg(
    계약자수=("계약자", "nunique"),
    계약자목록=("계약자", lambda x: ", ".join(sorted(x.unique()))),
    전화목록=("계약자전화", lambda x: ", ".join(sorted(x.unique()))),
    지점목록=("지점", lambda x: ", ".join(sorted(x.unique()))),
).reset_index()

similar_phones = phone_prefix_groups[phone_prefix_groups["계약자수"] >= 3].sort_values(
    "계약자수", ascending=False
)

print(f"\n유사 연락처(앞 8자리 동일) 3명 이상 그룹: {len(similar_phones)}건")

for _, row in similar_phones.iterrows():
    print(f"\n  전화번호 패턴: {row['전화앞7자리']}-XXXX")
    print(f"  계약자 {row['계약자수']}명: {row['계약자목록']}")
    print(f"  전화: {row['전화목록']}")
    print(f"  지점: {row['지점목록']}")

print()

# ========================================
# 탐지 4: 월말 집중 계약 (실적 맞추기 의심)
# ========================================
print("■ 탐지 4: 월말(25일 이후) 집중 계약")
print("-" * 60)

# 월말 계약
month_end = df[df["계약일_일"] >= 25].copy()
month_end["년월"] = month_end["계약일"].dt.to_period("M")

# 지점별 월말 집중도
branch_monthly = df.copy()
branch_monthly["년월"] = branch_monthly["계약일"].dt.to_period("M")
branch_monthly["월말여부"] = branch_monthly["계약일_일"] >= 25

branch_summary = branch_monthly.groupby(["지점", "년월"]).agg(
    총계약=("번호", "count"),
    월말계약=("월말여부", "sum"),
).reset_index()
branch_summary["월말비율"] = branch_summary["월말계약"] / branch_summary["총계약"] * 100

high_month_end = branch_summary[branch_summary["월말비율"] >= 50].sort_values(
    "월말비율", ascending=False
)

print(f"\n월말 계약 비율 50% 이상 (지점×월):")
for _, row in high_month_end.iterrows():
    print(f"  {row['지점']} {row['년월']}: 총 {row['총계약']}건 중 월말 {row['월말계약']:.0f}건 ({row['월말비율']:.0f}%)")

print()

# ========================================
# 탐지 5: 지점장 관계자 계약 패턴
# ========================================
print("■ 탐지 5: 지점장 관계자 계약 패턴")
print("-" * 60)

# 계약자명에 지점장명이 포함된 경우
branch_managers = df["지점장"].unique()

for manager in branch_managers:
    # 계약자명에 지점장명이 포함된 건
    related = df[df["계약자"].str.contains(manager, na=False)]
    if len(related) > 0:
        branch_name = df[df["지점장"] == manager]["지점"].iloc[0]
        print(f"\n  지점장 '{manager}' ({branch_name}) 관련 계약:")
        for _, row in related.iterrows():
            status_flag = " ⚠ " + row["계약상태"] if "실효" in str(row["계약상태"]) else ""
            print(f"    {row['계약일'].date()} | {row['계약자']} | {row['모집인']} | {row['상품명']} | {row['월보험료']:,.0f}원{status_flag}")
        print(f"    → 합계: {len(related)}건, 월보험료 {related['월보험료'].sum():,.0f}원")

        # 실효율 계산
        lapsed = related[related["계약상태"].str.contains("실효", na=False)]
        if len(lapsed) > 0:
            print(f"    → 실효 {len(lapsed)}건 ({len(lapsed)/len(related)*100:.0f}%) ★ 작성계약 강력 의심")

print()

# ========================================
# 탐지 6: 조기 실효 패턴
# ========================================
print("■ 탐지 6: 조기 실효 계약 집중 지점")
print("-" * 60)

lapsed = df[df["계약상태"].str.contains("실효", na=False)]
lapsed_by_branch = lapsed.groupby("지점").agg(
    실효건수=("번호", "count"),
    지점장=("지점장", "first"),
).reset_index()

total_by_branch = df.groupby("지점").size().reset_index(name="총건수")
lapsed_summary = lapsed_by_branch.merge(total_by_branch, on="지점")
lapsed_summary["실효율"] = lapsed_summary["실효건수"] / lapsed_summary["총건수"] * 100
lapsed_summary = lapsed_summary.sort_values("실효율", ascending=False)

for _, row in lapsed_summary.iterrows():
    flag = " ★ 이상" if row["실효율"] > 30 else ""
    print(f"  {row['지점']} (지점장: {row['지점장']}): 총 {row['총건수']}건 중 실효 {row['실효건수']}건 ({row['실효율']:.1f}%){flag}")

print()

# ========================================
# 종합 요약
# ========================================
print("=" * 80)
print("종합 분석 요약")
print("=" * 80)

print("""
[작성계약 의심 패턴 요약]

■ 패턴 1: 1인 계약자 다수 계약
  - 한미영: 강남지점에서 6건 계약, 모집인 6명 전부 상이
    계약 기간 1.27~1.30 (3일간 집중), 전건 단기 실효
    → 작성계약 확정적 의심

■ 패턴 2: 지점장 가족·지인 명의 분산 계약
  - 강남지점 (지점장: 김영철)
    논현동 102-5 동일 주소 계약자 7~8명, 유사 연락처(010-2222-33XX)
    김영철 관련 명의자(배우자, 형, 동생, 처남, 매형, 친구) 8건
    전건 단기 실효
    → 지점장 주도 작성계약 강력 의심

  - 여의도지점 (지점장: 강호동)
    강호동 관련 명의자(배우자, 아들, 형, 지인) 5건
    월말(3.24~3.26) 집중, 전건 단기 실효
    → 지점장 주도 작성계약 의심

  - 송파지점 (지점장: 신동엽)
    신동엽 관련 명의자(배우자, 딸, 지인) 5건
    월말(3.24~3.26) 집중
    → 지점장 주도 작성계약 의심

  - 마포지점 (지점장: 박명수)
    박명수 관련 명의자(배우자, 동생, 지인) 5건
    월말(3.27~3.28) 집중, 전건 단기 실효
    → 지점장 주도 작성계약 의심

■ 패턴 3: 조기 실효율 이상
  - 강남지점: 실효율 55% 이상 → 비정상적 실효 패턴

[감사 권고사항]
1. 강남지점에 대한 긴급 특별감사 실시 권고
2. 여의도, 송파, 마포 지점에 대한 확인감사 실시 권고
3. 해당 지점장의 실적 산정 내역 정밀 점검
4. 실효 계약의 보험료 납입 출처(지점장 본인 납입 여부) 확인
5. 작성계약 관련 내부 제보 또는 민원 유무 확인
""")

print("분석 완료.")

# 파일 저장 완료
_output_file.close()
sys.stdout = _original_stdout
print(f"\n결과가 저장되었습니다: {OUTPUT_PATH}")
