import uuid
from datetime import datetime, timezone
from sqlalchemy import Column, String, Boolean, DateTime, Date, Integer, Text, ForeignKey, UniqueConstraint
from sqlalchemy.dialects.postgresql import UUID, JSONB
from app.core.database import Base


def now_utc():
    return datetime.now(timezone.utc)


class BodyTypeMaster(Base):
    """Bus body types (LEGACY, STARLINE, SKYLINE, ...). Editable from the Production Masters screen."""
    __tablename__ = 'body_type_master'
    body_type_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String(100), unique=True, nullable=False)
    image_url = Column(String(500), nullable=True)
    is_active = Column(Boolean, nullable=False, default=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)


class ModelBodyTypeMap(Base):
    """Which body types a given vehicle model can be built in — drives the dealer order wizard's cascading dropdown."""
    __tablename__ = 'model_body_type_map'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    model_id = Column(UUID(as_uuid=True), ForeignKey('vehicle_model_master.model_id'), nullable=False)
    body_type_id = Column(UUID(as_uuid=True), ForeignKey('body_type_master.body_type_id'), nullable=False)

    __table_args__ = (UniqueConstraint('model_id', 'body_type_id', name='uq_model_body_type'),)


class CustomerSegmentMaster(Base):
    """The "surname" column — School / Staff / RP / etc. Editable from the Production Masters screen."""
    __tablename__ = 'customer_segment_master'
    segment_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String(100), unique=True, nullable=False)
    is_active = Column(Boolean, nullable=False, default=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)


class ModelSegmentMap(Base):
    """Which customer segments a given vehicle model is offered under."""
    __tablename__ = 'model_segment_map'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    model_id = Column(UUID(as_uuid=True), ForeignKey('vehicle_model_master.model_id'), nullable=False)
    segment_id = Column(UUID(as_uuid=True), ForeignKey('customer_segment_master.segment_id'), nullable=False)

    __table_args__ = (UniqueConstraint('model_id', 'segment_id', name='uq_model_segment'),)


class FeatureSegmentMap(Base):
    """Which customer segments a given special feature is visible for."""
    __tablename__ = 'feature_segment_map'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    feature_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_master.feature_id'), nullable=False)
    segment_id = Column(UUID(as_uuid=True), ForeignKey('customer_segment_master.segment_id'), nullable=False)

    __table_args__ = (UniqueConstraint('feature_id', 'segment_id', name='uq_feature_segment'),)



class RtoMaster(Base):
    """RTO compliance/registration options offered on a dealer order. Editable from the Production Masters screen."""
    __tablename__ = 'rto_master'
    rto_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    name = Column(String(150), nullable=False)
    description = Column(Text)
    is_active = Column(Boolean, nullable=False, default=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)


class SpecialFeatureMaster(Base):
    """
    The dealer order's special-feature checklist (per the "Req spec" sheet) — section-grouped,
    each with an input_type telling the order wizard what control to render:
    BOOLEAN (tick), DROPDOWN (select from SpecialFeatureOptionMaster), or TEXT (free note).
    Editable from the Production Masters screen; additions/removals show up in the dealer
    portal immediately since the wizard reads this table live.
    """
    __tablename__ = 'special_feature_master'
    feature_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    section = Column(String(100), nullable=False)  # Dealer/Customer, Interior Features, Exterior Specifications
    feature_name = Column(String(200), nullable=False)
    input_type = Column(String(20), nullable=False, default='BOOLEAN')  # BOOLEAN / DROPDOWN / TEXT
    sequence_no = Column(Integer, nullable=False, default=0)
    is_active = Column(Boolean, nullable=False, default=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)

    @property
    def name(self) -> str:
        return self.feature_name or ""


class SpecialFeatureOptionMaster(Base):
    """The selectable values for a DROPDOWN-type special feature (e.g. Window glass colour -> Black/Grey/Blue)."""
    __tablename__ = 'special_feature_option_master'
    option_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    feature_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_master.feature_id'), nullable=False)
    option_value = Column(String(150), nullable=False)
    image_url = Column(String(500), nullable=True)
    sequence_no = Column(Integer, nullable=False, default=0)
    is_active = Column(Boolean, nullable=False, default=True)
    
    restricted_model_ids = Column(JSONB, nullable=True)
    restricted_body_type_ids = Column(JSONB, nullable=True)
    restricted_segment_ids = Column(JSONB, nullable=True)
    restricted_combinations = Column(JSONB, nullable=True)

    @property
    def name(self) -> str:
        return self.option_value or ""



class SeatModelConfiguration(Base):
    """
    Dynamic mapping rules defining which Seat Model, Supplier, and Dimensions are valid
    for a given Body Type, Seat Type, and Seating Layout Size.
    """
    __tablename__ = 'seat_model_configuration'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    body_type_id = Column(UUID(as_uuid=True), ForeignKey('body_type_master.body_type_id'), nullable=False)
    seat_type = Column(String(100), nullable=False)    # e.g., 'HHR', 'Push Back'
    layout_size = Column(String(50), nullable=False)   # e.g., '2x2', '3x2'
    
    seat_model_option_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_option_master.option_id'), nullable=False)
    supplier_option_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_option_master.option_id'), nullable=False)
    dimensions_option_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_option_master.option_id'), nullable=False)
    image_url = Column(String(500), nullable=True)
    
    is_active = Column(Boolean, nullable=False, default=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)
class DealerClientMaster(Base):
    """
    A dealer's own client (the school/institution/company actually buying the buses).
    One shared table between the dealer portal and the sales portal — whichever side adds
    a client, both see the same row, so there's no way to end up with duplicates.
    """
    __tablename__ = 'dealer_client_master'
    client_id = Column(String(50), primary_key=True)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'), nullable=False)
    name = Column(String(200), nullable=False)
    contact_person = Column(String(150))
    phone = Column(String(20))
    email = Column(String(150))
    address = Column(Text)
    city = Column(String(100))
    state = Column(String(100))
    is_active = Column(Boolean, nullable=False, default=True)
    created_by_dealer = Column(Boolean, nullable=False, default=False)
    created_by_user_id = Column(UUID(as_uuid=True), ForeignKey('login_users.user_id'), nullable=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)
    updated_at = Column(DateTime(timezone=True), default=now_utc, onupdate=now_utc)


class DealerOrder(Base):
    """
    A dealer-placed order header. Moves DRAFT -> SUBMITTED -> SALES_REVIEW -> PENDING_DEALER_ACK
    -> CONFIRMED, with DEALER_EDITED looping back to SALES_REVIEW until both sides agree.
    """
    __tablename__ = 'dealer_order'
    order_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    order_no = Column(String(50), unique=True, nullable=False)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'), nullable=False)
    client_id = Column(String(50), ForeignKey('client_master.client_id'), nullable=False)
    status = Column(String(30), nullable=False, default='DRAFT')
    remarks = Column(Text)
    rep_name = Column(String(100), nullable=True)
    rep_contact = Column(String(50), nullable=True)
    billing_by = Column(String(10), nullable=True)  # 'DEALER' or 'CLIENT'; locked after CONFIRMED
    submitted_at = Column(DateTime(timezone=True))
    confirmed_at = Column(DateTime(timezone=True))
    build_order_id = Column(UUID(as_uuid=True), nullable=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)
    updated_at = Column(DateTime(timezone=True), default=now_utc, onupdate=now_utc)

    from sqlalchemy.orm import relationship
    dealer = relationship('CustomerMaster', foreign_keys=[dealer_id])


class DealerOrderVehicle(Base):
    """One vehicle-line (model + body type + segment + RTO + qty) within a dealer order."""
    __tablename__ = 'dealer_order_vehicle'
    order_vehicle_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    order_id = Column(UUID(as_uuid=True), ForeignKey('dealer_order.order_id'), nullable=False)
    model_id = Column(UUID(as_uuid=True), ForeignKey('vehicle_model_master.model_id'), nullable=False)
    body_type_id = Column(UUID(as_uuid=True), ForeignKey('body_type_master.body_type_id'), nullable=False)
    segment_id = Column(UUID(as_uuid=True), ForeignKey('customer_segment_master.segment_id'), nullable=False)
    rto_id = Column(UUID(as_uuid=True), ForeignKey('rto_master.rto_id'), nullable=True)
    qty = Column(Integer, nullable=False, default=1)
    sequence_no = Column(Integer, nullable=False, default=0)
    notes = Column(Text)
    is_edited = Column(Boolean, nullable=False, default=False)
    edited_fields = Column(JSONB, nullable=True)

    from sqlalchemy.orm import relationship
    model = relationship('VehicleModelMaster', foreign_keys=[model_id])
    body_type = relationship('BodyTypeMaster', foreign_keys=[body_type_id])
    segment = relationship('CustomerSegmentMaster', foreign_keys=[segment_id])
    order = relationship('DealerOrder', foreign_keys=[order_id])
    features = relationship('DealerOrderVehicleFeature', back_populates='vehicle', foreign_keys='DealerOrderVehicleFeature.order_vehicle_id', lazy='selectin')


class DealerOrderVehicleChassis(Base):
    """Optional per-unit chassis numbers and delivery dates for a vehicle line."""
    __tablename__ = 'dealer_order_vehicle_chassis'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    order_vehicle_id = Column(UUID(as_uuid=True), ForeignKey('dealer_order_vehicle.order_vehicle_id'), nullable=False)
    seq_no = Column(Integer, nullable=False, default=1)
    chassis_no = Column(String(100))
    expected_delivery_date = Column(Date, nullable=True)


class DealerOrderVehicleFeature(Base):
    """
    A single special-feature selection on a vehicle line. Which of bool_value/option_id/text_value
    is populated depends on the feature's input_type (BOOLEAN / DROPDOWN / TEXT respectively).
    """
    __tablename__ = 'dealer_order_vehicle_feature'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    order_vehicle_id = Column(UUID(as_uuid=True), ForeignKey('dealer_order_vehicle.order_vehicle_id'), nullable=False)
    feature_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_master.feature_id'), nullable=False)
    feature_option_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_option_master.option_id'), nullable=True)
    bool_value = Column(Boolean)
    text_value = Column(Text)
    image_url = Column(String(500), nullable=True)

    __table_args__ = (UniqueConstraint('order_vehicle_id', 'feature_id', name='uq_order_vehicle_feature'),)

    from sqlalchemy.orm import relationship
    vehicle = relationship('DealerOrderVehicle', back_populates='features')
    feature_master = relationship('SpecialFeatureMaster', foreign_keys=[feature_id])
    option = relationship('SpecialFeatureOptionMaster', foreign_keys=[feature_option_id])


class DealerOrderActivityLog(Base):
    """The audit trail behind the confirm/edit loop — one row per state transition."""
    __tablename__ = 'dealer_order_activity_log'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    order_id = Column(UUID(as_uuid=True), ForeignKey('dealer_order.order_id'), nullable=False)
    action = Column(String(30), nullable=False)  # SUBMITTED / SALES_CONFIRMED / CHANGES_REQUESTED / DEALER_ACKNOWLEDGED / DEALER_EDITED
    performed_by_dealer = Column(Boolean, nullable=False, default=False)
    performed_by_user_id = Column(UUID(as_uuid=True), ForeignKey('login_users.user_id'), nullable=True)
    notes = Column(Text)
    created_at = Column(DateTime(timezone=True), default=now_utc)


class DealerPortalLog(Base):
    """Dealer portal login sessions — same shape as VendorPortalLog, revocable server-side."""
    __tablename__ = 'dealer_portal_log'
    log_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'), nullable=False)
    session_token = Column(String(128), unique=True, nullable=False)
    ip_address = Column(String(50))
    user_agent = Column(Text)
    issued_at = Column(DateTime(timezone=True), default=now_utc, nullable=False)
    expires_at = Column(DateTime(timezone=True), nullable=False)
    invalidated_at = Column(DateTime(timezone=True))


class DealerPortalActionLog(Base):
    """Every dealer-portal action, for audit — same shape as VendorPortalActionLog."""
    __tablename__ = 'dealer_portal_action_log'
    action_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'), nullable=False)
    action_type = Column(String(50), nullable=False)
    entity_type = Column(String(50))
    entity_id = Column(String(50))
    action_details = Column(JSONB)
    ip_address = Column(String(50))
    created_at = Column(DateTime(timezone=True), default=now_utc)


class DealerPortalAdminActionLog(Base):
    """Staff-side changes to a dealer's portal access — same shape as VendorPortalAdminActionLog."""
    __tablename__ = 'dealer_portal_admin_action_log'
    action_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    admin_user_id = Column(UUID(as_uuid=True), nullable=False)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'))
    action_type = Column(String(50), nullable=False)
    action_details = Column(JSONB)
    ip_address = Column(String(50))
    created_at = Column(DateTime(timezone=True), default=now_utc)


class DealerRequest(Base):
    """
    A dealer's request for quotation or spare parts.
    """
    __tablename__ = 'dealer_request'
    request_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'), nullable=False)
    request_type = Column(String(50), nullable=False)  # QUOTATION, SPARE_PARTS, SERVICE
    details = Column(Text, nullable=False)
    photo_url = Column(String(500), nullable=True)
    photo_urls = Column(JSONB, nullable=True)
    status = Column(String(30), nullable=False, default='PENDING')  # PENDING, ACKNOWLEDGED
    acknowledged_by = Column(UUID(as_uuid=True), ForeignKey('login_users.user_id'), nullable=True)
    acknowledged_at = Column(DateTime(timezone=True), nullable=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)
    updated_at = Column(DateTime(timezone=True), default=now_utc, onupdate=now_utc)

class DealerVehicleTemplate(Base):
    """A saved vehicle configuration template for a dealer."""
    __tablename__ = 'dealer_vehicle_template'
    template_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    dealer_id = Column(String(50), ForeignKey('customer_master.customer_id'), nullable=False)
    name = Column(String(100), nullable=False)
    model_id = Column(UUID(as_uuid=True), ForeignKey('vehicle_model_master.model_id'), nullable=False)
    body_type_id = Column(UUID(as_uuid=True), ForeignKey('body_type_master.body_type_id'), nullable=False)
    segment_id = Column(UUID(as_uuid=True), ForeignKey('customer_segment_master.segment_id'), nullable=False)
    created_at = Column(DateTime(timezone=True), default=now_utc)
    updated_at = Column(DateTime(timezone=True), default=now_utc, onupdate=now_utc)


class DealerVehicleTemplateFeature(Base):
    """Special features selected in a saved vehicle template."""
    __tablename__ = 'dealer_vehicle_template_feature'
    id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    template_id = Column(UUID(as_uuid=True), ForeignKey('dealer_vehicle_template.template_id', ondelete='CASCADE'), nullable=False)
    feature_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_master.feature_id'), nullable=False)
    feature_option_id = Column(UUID(as_uuid=True), ForeignKey('special_feature_option_master.option_id'), nullable=True)
    bool_value = Column(Boolean)
    text_value = Column(Text)
    image_url = Column(String(500), nullable=True)

    __table_args__ = (UniqueConstraint('template_id', 'feature_id', name='uq_template_feature'),)


class SeatingLayoutMaster(Base):
    __tablename__ = 'seating_layout_master'
    layout_id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4)
    layout_no = Column(String(100), nullable=False, unique=True)
    chassis_model = Column(String(100), nullable=False)
    body_type = Column(String(100), nullable=False)
    segment = Column(String(100), nullable=False)
    door_type = Column(String(100), nullable=False)
    seat_type = Column(String(100), nullable=False)
    seating_type = Column(String(100), nullable=False)
    seating_capacity = Column(String(100), nullable=False)
    image_url = Column(String(500), nullable=True)
    pdf_url = Column(String(500), nullable=True)
    created_at = Column(DateTime(timezone=True), default=now_utc)

