// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;

/**
 * @title Flight Confirmation Contract
 * @dev A contract for confirming flights on the blockchain with signatures from multiple parties
 */
contract FlightConfirmation {
    struct FlightDetails {
        uint256 departureTime;
        uint256 arrivalTime;
        string departureAirport;
        string arrivalAirport;
        string flightNumber;
    }

    struct Confirmation {
        address manufacturer;
        address logisticsProvider;
        address buyer;
        bool manufacturerConfirmed;
        bool logisticsConfirmed;
        bool buyerConfirmed;
        uint256 timestamp;
        bytes32 flightHash;
    }

    mapping(bytes32 => Confirmation) public confirmations;
    mapping(bytes32 => FlightDetails) public flightDetails;

    event FlightConfirmed(
        bytes32 indexed flightId,
        address confirmer,
        uint256 timestamp
    );

    event FlightCreated(
        bytes32 indexed flightId,
        string flightNumber,
        uint256 departureTime
    );

    /**
     * @dev Stores flight details
     */
    function storeFlightDetails(
        bytes32 flightId,
        uint256 departureTime,
        uint256 arrivalTime,
        string memory departureAirport,
        string memory arrivalAirport,
        string memory flightNumber
    ) external {
        flightDetails[flightId] = FlightDetails({
            departureTime: departureTime,
            arrivalTime: arrivalTime,
            departureAirport: departureAirport,
            arrivalAirport: arrivalAirport,
            flightNumber: flightNumber
        });

        emit FlightCreated(flightId, flightNumber, departureTime);
    }

    /**
     * @dev Manufacturer confirms flight
     */
    function confirmFlightAsManufacturer(bytes32 flightId) external {
        confirmations[flightId].manufacturer = msg.sender;
        confirmations[flightId].manufacturerConfirmed = true;
        confirmations[flightId].timestamp = block.timestamp;
        confirmations[flightId].flightHash = flightId;

        emit FlightConfirmed(flightId, msg.sender, block.timestamp);
    }

    /**
     * @dev Logistics provider confirms flight
     */
    function confirmFlightAsLogistics(bytes32 flightId) external {
        confirmations[flightId].logisticsProvider = msg.sender;
        confirmations[flightId].logisticsConfirmed = true;
        confirmations[flightId].timestamp = block.timestamp;
        confirmations[flightId].flightHash = flightId;

        emit FlightConfirmed(flightId, msg.sender, block.timestamp);
    }

    /**
     * @dev Buyer confirms flight
     */
    function confirmFlightAsBuyer(bytes32 flightId) external {
        confirmations[flightId].buyer = msg.sender;
        confirmations[flightId].buyerConfirmed = true;
        confirmations[flightId].timestamp = block.timestamp;
        confirmations[flightId].flightHash = flightId;

        emit FlightConfirmed(flightId, msg.sender, block.timestamp);
    }

    /**
     * @dev Check if flight is confirmed by all parties
     */
    function isFlightFullyConfirmed(bytes32 flightId) external view returns (bool) {
        Confirmation memory confirmation = confirmations[flightId];
        return confirmation.manufacturerConfirmed &&
               confirmation.logisticsConfirmed &&
               confirmation.buyerConfirmed;
    }

    /**
     * @dev Get confirmation status for a flight
     */
    function getConfirmationStatus(bytes32 flightId) external view returns (
        bool manufacturerConfirmed,
        bool logisticsConfirmed, 
        bool buyerConfirmed,
        uint256 timestamp
    ) {
        Confirmation memory confirmation = confirmations[flightId];
        return (
            confirmation.manufacturerConfirmed,
            confirmation.logisticsConfirmed,
            confirmation.buyerConfirmed,
            confirmation.timestamp
        );
    }
}