"""
Transportation Parser Tool Class - Handle transportation-related parsing operations
"""

import json
from datetime import datetime
from typing import Dict, List, Any


class TransportationParser:
    """Transportation Parser Tool Class"""
    
    @staticmethod
    def parse_segment(one_segment: Dict[str, Any]) -> Dict[str, Any]:
        """
        Parse single transportation segment
        
        Args:
            one_segment: Transportation segment data
            
        Returns:
            Parsed transportation segment data
        """
        if one_segment['tripType'] == 'T':
            return {
                'tripType': 'train',
                'fromStationCode': one_segment['train']['fromCode'],
                'toStationCode': one_segment['train']['toCode'],
                'departureTime': one_segment['train']['depAt'],
                'arrivalTime': one_segment['train']['arrAt'],
                'trainNo': one_segment['train']['trainNo']
            }
        elif one_segment['tripType'] == 'SC':
            return {
                'tripType': 'driving',
                'fromStationCode': one_segment['point']['fromCode'],
                'toStationCode': one_segment['point']['toCode'],
                'departureTime': one_segment['point']['depAt'],
                'arrivalTime': one_segment['point']['arrAt']
            }
        elif one_segment['tripType'] == 'B':
            return {
                'tripType': 'bus',
                'fromStationCode': one_segment['bus']['fromCode'],
                'toStationCode': one_segment['bus'].get('toCode', one_segment['bus'].get('toStation', '')),
                'departureTime': one_segment['bus']['depEndAt'],
                'arrivalTime': one_segment['bus']['arrAt']
            }
        elif one_segment['tripType'] == 'F':
            return {
                'tripType': 'flight',
                'fromStationCode': one_segment['flight']['fromCode'],
                'toStationCode': one_segment['flight']['toCode'],
                'departureTime': one_segment['flight']['depAt'],
                'arrivalTime': one_segment['flight']['arrAt'],
                'flightNo': one_segment['flight']['flightNo']
            }
        elif one_segment['tripType'] == 'S':
            return {
                'tripType': 'ship',
                'fromStationCode': one_segment['ship']['fromCode'],
                'toStationCode': one_segment['ship']['toCode'],
                'departureTime': one_segment['ship']['depAt'],
                'arrivalTime': one_segment['ship']['arrAt'],
                'shipName': one_segment['ship']['shipName']
            }
        elif one_segment['tripType'] == 'D':
            return {
                'tripType': 'drive',
                'fromStationCode': one_segment['point']['fromCode'],
                'toStationCode': one_segment['point']['toCode'],
                'departureTime': one_segment['point']['depAt'],
                'arrivalTime': one_segment['point']['arrAt']
            }
        else:
            print(f'未识别的tripType: {one_segment["tripType"]}')
            return one_segment
    
    @staticmethod
    def parse_transportation_pool(transportation_json: str, reference: str, depature: str, arrive: str) -> List[Dict[str, Any]]:
        """
        Parse transportation pool data
        
        Args:
            transportation_json: Transportation JSON string
            reference: Reference data
            depature: Departure
            arrive: Destination
            
        Returns:
            Parsed transportation pool list
        """
        transportation_pool = []
        transportation_data = json.loads(transportation_json)
        
        for key in transportation_data.keys():
            for transportation_way in transportation_data[key]:
                try:
                    transportation_way["key"] = key
                    segments = [TransportationParser.parse_segment(segment) for segment in transportation_way['segments']]
                    
                    if len(segments) > 0:
                        depature_time = segments[0]["departureTime"]
                        flight_time = segments[-1]["arrivalTime"]
                        time_format = "%Y-%m-%d %H:%M"
                        depature_time_f = datetime.strptime(depature_time, time_format)
                        flight_time_f = datetime.strptime(flight_time, time_format)
                        
                        for segment in segments:
                            cur_depature_time_str = segment["departureTime"]
                            cur_flight_time_str = segment["arrivalTime"]
                            cur_depature_time = datetime.strptime(cur_depature_time_str, time_format)
                            cur_flight_time = datetime.strptime(cur_flight_time_str, time_format)

                            if cur_flight_time > flight_time_f:
                                flight_time = cur_flight_time_str
                                flight_time_f = cur_flight_time
                            if cur_depature_time < depature_time_f:
                                depature_time = cur_depature_time_str
                                depature_time_f = cur_depature_time
                                
                        if flight_time_f < depature_time_f:
                            print(f"交通时间错误: {depature_time_f} {flight_time_f}")
                    else:
                        depature_time = ""
                        flight_time = ""
                        
                    transportation_way["key"] = key
                    t_type = ""
                    key_list = key.split("->")
                    
                    if len(key_list) == 2 and depature != "":
                        if depature.lower() in key_list[0].lower() and depature.lower() not in key_list[1].lower():
                            t_type = "to"
                        elif depature.lower() in key_list[1].lower() and depature.lower() not in key_list[0].lower():
                            t_type = "back"
                            
                    transportation_way["t_type"] = t_type
                    transportation_way["depature_time"] = depature_time
                    transportation_way["flight_time"] = flight_time
                    transportation_way['planid'] = transportation_way['tripId4V1Hash']
                    transportation_way["segments"] = segments
                    planid = str(transportation_way['planid'])
                    
                    if planid in reference:
                        transportation_pool.append(transportation_way)
                        
                except Exception as e:
                    print(f"解析交通失败: {e}")
                    
        if len(transportation_pool) < 1:
            print("未匹配到交通，交通池为空")
            
        return transportation_pool

    def calculate_transport_hours(self, start_time_str: str, end_time_str: str) -> float:
        """
        Calculate transportation time (hours)

        Args:
            start_time_str: Start time string
            end_time_str: End time string

        Returns:
            Transportation time (hours)
        """
        start_time = datetime.strptime(start_time_str, "%Y-%m-%d %H:%M")
        end_time = datetime.strptime(end_time_str, "%Y-%m-%d %H:%M")

        # Check if it crosses the day
        if end_time.day != start_time.day:
            # Calculate the time difference from midnight to end_time
            total_time = datetime(start_time.year, start_time.month, start_time.day, 23, 59, 59) - start_time
        else:
            # Calculate the time difference directly
            total_time = end_time - start_time

        # Convert the time difference to hours
        hours = total_time.total_seconds() / 3600
        return hours

    def check_title_transportation_mismatch(self, period: str, title: str) -> bool:
        """
        Check if the title and transportation time do not match

        Args:
            period: Time period
            title: Title

        Returns:
            Whether it does not match
        """
        title = title.lower()

        if period == "Evening":
            check_list = ['morning arrival', 'morning departure', 'afternoon arrival', 'afternoon departure',
                          '上午到达', '上午启程', '下午到达', '下午启程']
        elif period == "Afternoon":
            check_list = ['morning arrival', 'morning departure', 'evening arrival', 'evening departure',
                          '上午到达', '上午启程', '晚上到达', '晚上启程']
        elif period == "Morning":
            check_list = ['afternoon arrival', 'afternoon departure', 'evening arrival', 'evening departure',
                          '下午到达', '下午启程', '晚上到达', '晚上启程']
        else:
            return False

        return any(item in title for item in check_list)

    def check_period_transportation_mismatch(self, item: Dict) -> bool:
        """
        Check if the time period and transportation time do not match

        Args:
            item: Transportation item

        Returns:
            Whether it does not match
        """
        start_time = datetime.strptime(item['start_time'], "%Y-%m-%d %H:%M")

        if item['period'].lower() == 'morning' or item['period'] == "上午":
            return start_time > datetime(start_time.year, start_time.month, start_time.day, 12, 30)
        elif item['period'].lower() == 'afternoon' or item['period'] == "下午":
            return (start_time < datetime(start_time.year, start_time.month, start_time.day, 11, 30) or
                    start_time > datetime(start_time.year, start_time.month, start_time.day, 18, 0))
        elif item['period'].lower() == 'evening' or item['period'] == "晚上":
            return start_time < datetime(start_time.year, start_time.month, start_time.day, 17, 0)

        return False

    def is_cross_day_transportation(self, minutes: int) -> bool:
        """
        Check if it is a cross-day transportation

        Args:
            minutes: Transportation time (minutes)

        Returns:
            Whether it is a cross-day transportation
        """
        return minutes >= 1440

    def check_evening_transportation_no_daytime_activities(self, day_items: List[Dict],
                                                           day_trans_start: str, trans_day_index: str) -> bool:
        """
        Check if there is a situation where the transportation is in the evening but there is no arrangement in the daytime

        Args:
            day_items: List of day itinerary items
            day_trans_start: Day transportation start time
            trans_day_index: Transportation date index

        Returns:
            Whether there is a problem
        """
        # Check if there is a sightseeing arrangement
        has_poi = any(item['type'].lower() == 'attraction' and
                      item['period'].lower() not in ['evening', '晚上']
                      for item in day_items)

        if not has_poi:
            dt_start = datetime.strptime(day_trans_start, "%Y-%m-%d %H:%M")
            return (dt_start > datetime(dt_start.year, dt_start.month, dt_start.day, 15, 0, 0)
                    and trans_day_index != '1')

        return False
