import asyncio
import uuid
import os
import sys
from datetime import datetime, timezone
from sqlalchemy import select
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker

# Add project root to sys.path
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

from app.models.rm_models import (
    ProcurementSourceMaster,
    MaterialTypeMaster,
    PoStatusMaster,
    StoreMaster
)
from app.models.sales_models import CustomerTypeMaster
from app.models.core_models import LoginUsers
from app.core.security import hash_password
from dotenv import load_dotenv

load_dotenv()

DATABASE_URL = os.environ.get("DATABASE_URL")
if not DATABASE_URL:
    raise ValueError("DATABASE_URL environment variable is not set in backend/.env")

engine = create_async_engine(DATABASE_URL)
Session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)

async def seed():
    async with Session() as db:
        # 1. Procurement Sources
        sources = ['BOP', 'In-House BOP', 'On-Plant', 'Imported', 'Consignment']
        for name in sources:
            exists = (await db.execute(select(ProcurementSourceMaster).where(ProcurementSourceMaster.name == name))).scalar_one_or_none()
            if not exists:
                db.add(ProcurementSourceMaster(
                    id=uuid.uuid4(),
                    name=name,
                    description=f"{name} procurement source",
                    is_active=True,
                    created_at=datetime.now(timezone.utc)
                ))

        # 2. Material Types
        types = ['Raw Material', 'Consumable', 'Semi-Finished', 'Packing Material', 'Capital Item']
        for name in types:
            exists = (await db.execute(select(MaterialTypeMaster).where(MaterialTypeMaster.name == name))).scalar_one_or_none()
            if not exists:
                db.add(MaterialTypeMaster(
                    id=uuid.uuid4(),
                    name=name,
                    description=f"{name} material type",
                    is_active=True,
                    created_at=datetime.now(timezone.utc)
                ))

        # 3. PO Statuses
        statuses = [
            ('DRAFT', 'Draft'),
            ('PENDING_APPROVAL', 'Pending Approval'),
            ('BLOCKED', 'Blocked - Price Variance'),
            ('RELEASED', 'Released'),
            ('PARTIALLY_RECEIVED', 'Partially Received'),
            ('COMPLETED', 'Completed'),
            ('CLOSED', 'Closed'),
            ('CANCELLED', 'Cancelled'),
            ('ASN_SHIPPED', 'ASN Shipped'),
            ('UPDATED_ASN_SHIPPED', 'Updated ASN Shipped'),
            ('ACKNOWLEDGED', 'Acknowledged'),
            ('IN_TRANSIT', 'In Transit'),
        ]
        for code, name in statuses:
            exists = (await db.execute(select(PoStatusMaster).where(PoStatusMaster.code == code))).scalar_one_or_none()
            if not exists:
                db.add(PoStatusMaster(
                    id=uuid.uuid4(),
                    code=code,
                    name=name,
                    description=f"{name} status",
                    created_at=datetime.now(timezone.utc)
                ))

        # 4. Default Stores
        stores = [
            ('Main Store', 'Main warehouse facility'),
            ('Floor Inventory', 'Shop floor production area'),
            ('Rejection Store', 'Defective or rejected goods holding'),
            ('QA Quarantine', 'Incoming goods quality inspection area'),
        ]
        for name, location in stores:
            exists = (await db.execute(select(StoreMaster).where(StoreMaster.store_name == name))).scalar_one_or_none()
            if not exists:
                db.add(StoreMaster(
                    store_id=uuid.uuid4(),
                    store_name=name,
                    location=location,
                    is_active=True,
                    created_at=datetime.now(timezone.utc)
                ))

        # 5. Customer Types
        customer_types = [
            ('DEALER', 'Dealer'),
            ('DIRECT', 'Direct Customer'),
        ]
        for code, name in customer_types:
            exists = (await db.execute(select(CustomerTypeMaster).where(CustomerTypeMaster.type_code == code))).scalar_one_or_none()
            if not exists:
                db.add(CustomerTypeMaster(
                    type_code=code,
                    name=name,
                    is_active=True
                ))

        # 6. Default Users
        # `name` is a real person's display name, independent of both the login username
        # (employee_code) and the role — this is demo/dev seed data only, meant to be renamed
        # (or replaced entirely) from Access Control > Users once real employees are onboarded.
        # The point being illustrated: any of these people could be assigned any role_code
        # below and would immediately get exactly what that role's permission matrix grants —
        # access is resolved by role_id, never by who they are.
        users = [
            ('admin', 'ADMIN', 'admin@example.com', 'Admin User'),
            ('sales_mgr', 'SALES_MGR', 'sales_mgr@example.com', 'Rahul Sharma'),
            ('sales_exec', 'SALES_EXEC', 'sales_exec@example.com', 'Ajay Verma'),
            ('procurement_mgr', 'PROCUREMENT_MGR', 'procurement_mgr@example.com', 'Vikram Nair'),
            ('store_mgr', 'STORE_MGR', 'store_mgr@example.com', 'Suresh Iyer'),
            ('finance_mgr', 'FINANCE_MGR', 'finance_mgr@example.com', 'Priya Menon'),
            ('production_mgr', 'PRODUCTION_MGR', 'production_mgr@example.com', 'Karthik Rao'),
            ('engineering_head', 'ENGINEERING_HEAD', 'eng_head@example.com', 'Deepak Joshi'),
            ('viewer', 'VIEWER', 'viewer@example.com', 'Read Only User'),
        ]
        seed_password = os.environ.get('SEED_DEFAULT_PASSWORD')
        if not seed_password:
            raise SystemExit('Set SEED_DEFAULT_PASSWORD before running the seed (initial password for the demo users).')
        default_pwd_hash = hash_password(seed_password)
        for username, role, email, full_name in users:
            exists = (await db.execute(select(LoginUsers).where(LoginUsers.employee_code == username))).scalar_one_or_none()
            if not exists:
                db.add(LoginUsers(
                    user_id=uuid.uuid4(),
                    employee_code=username,
                    name=full_name,
                    email=email,
                    password_hash=default_pwd_hash,
                    role_code=role,
                    is_active=True
                ))

        await db.commit()
        print('Seed data inserted successfully.')

if __name__ == "__main__":
    asyncio.run(seed())
