import cv2
import numpy as np
import hyperlpr3 as lpr3
import os
from PIL import Image, ImageDraw, ImageFont
import requests
import json
import time

con = 0.75  # 置信度阈值
API_url = "http://localhost:8087/api/payment"
MIN_CONSECUTIVE_FRAMES = 5  # 需连续识别到同一车牌的最小帧数
RECORD_INTERVAL = 30  # 同一车牌发送间隔(秒)
plate_counter = {}  # 车牌连续计数 {车牌: 计数}
last_record_time = {}  # 车牌最后记录时间 {车牌: 时间戳}


def send_plate_to_server(plate_number):
    """发送车牌号到Spring Boot后端"""
    payload = {"plate": plate_number}
    try:
        response = requests.post(
            API_url,
            data=json.dumps(payload),
            headers={'Content-Type': 'application/json'},
            timeout=2
        )
        if response.status_code == 200:
            print(f"✅ 车牌发送成功: {plate_number}")
            return True
        else:
            print(f"⚠️ 服务端错误: {response.status_code} - {response.text}")
            return False
    except Exception as e:
        print(f"❌ 发送失败: {e}")
        return False


def draw_plate_on_image(img, box, text, font):
    """修复后的绘制函数，正确处理中文字符"""
    x1, y1, x2, y2 = box

    # 使用OpenCV绘制矩形框
    cv2.rectangle(img, (x1, y1), (x2, y2), (139, 139, 102), 2, cv2.LINE_AA)
    cv2.rectangle(img, (x1, y1 - 25), (x2, y1), (139, 139, 102), -1)

    # 关键修复：将BGR转换为RGB
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    data = Image.fromarray(img_rgb)
    draw = ImageDraw.Draw(data)

    # 绘制文字
    draw.text((x1 + 5, y1 - 20), text, (255, 255, 255), font=font)

    # 转换回BGR格式
    res = cv2.cvtColor(np.asarray(data), cv2.COLOR_RGB2BGR)
    return res


def save_txt(code):
    """将识别的车牌号保存到文本文件"""
    file_path = 'piu.txt'
    try:
        # 读取现有行数
        try:
            with open(file_path, 'r', encoding='utf-8') as fr:
                lines = fr.readlines()
                last_line = len(lines)
        except:
            last_line = 0

        # 追加新行
        with open(file_path, 'a', encoding='utf-8') as f:
            f.write(f"{last_line + 1} {code}\n")
            print(f"📝 保存车牌: {code}")
    except Exception as e:
        print(f"❌ 文件保存失败: {e}")


# 初始化字体和识别器
font_ch = ImageFont.truetype("../resource/font/platech.ttf", 20, 0)
catcher = lpr3.LicensePlateCatcher(detect_level=lpr3.DETECT_LEVEL_HIGH)

# 视频输入和输出设置
cap = cv2.VideoCapture("../resource/video/车牌付.mp4")

# 获取视频属性用于输出
fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))

# 创建输出视频文件
output_dir = "output_videos"
if not os.path.exists(output_dir):
    os.makedirs(output_dir)

output_path = os.path.join(output_dir, "processed_plate_video.mp4")
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
out = cv2.VideoWriter(output_path, fourcc, fps, (width, height))

print(f"📹 视频信息: {width}x{height}, {fps}FPS")
print(f"📁 输出视频将保存至: {output_path}")

cap.set(cv2.CAP_PROP_BUFFERSIZE, 1)

frame_count = 0
start_time = time.time()

while cap.isOpened():
    ret, frame = cap.read()
    if not ret:
        break

    frame_count += 1
    current_plates = set()

    # 车牌识别
    results = catcher(frame)

    # 绘制识别结果
    for code, confidence, type_idx, box in results:
        if confidence < con:
            continue

        current_plates.add(code)
        text = f"{code}-{confidence:.2f}"
        frame = draw_plate_on_image(frame, box, text, font_ch)

        # 更新连续计数
        plate_counter[code] = plate_counter.get(code, 0) + 1

    # 处理连续识别逻辑
    for plate in list(plate_counter.keys()):
        if plate not in current_plates:
            plate_counter[plate] = 0
            continue

        if plate_counter[plate] >= MIN_CONSECUTIVE_FRAMES:
            current_time = time.time()
            last_time = last_record_time.get(plate, 0)

            if current_time - last_time > RECORD_INTERVAL:
                save_txt(plate)
                # send_plate_to_server(plate)  # 需要时取消注释
                last_record_time[plate] = current_time
                plate_counter[plate] = 0

    # 写入输出视频
    out.write(frame)

    # 显示处理进度
    if frame_count % 30 == 0:
        elapsed = time.time() - start_time
        print(f"📊 已处理 {frame_count} 帧, 耗时: {elapsed:.1f}秒")

    # 显示当前帧
    display_frame = cv2.resize(frame, (800, 600))
    cv2.imshow('视频', display_frame)

    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源
cap.release()
out.release()
cv2.destroyAllWindows()

# 计算处理时间
end_time = time.time()
total_time = end_time - start_time
print(f"✅ 处理完成！")
print(f"⏱️ 总处理时间: {total_time:.2f}秒")
print(f"📁 输出视频保存为: {output_path}")
print(f"📄 识别结果保存为: piu.txt")